Skip to content

Commit 7e904b4

Browse files
authored
feat!: update rpc and openapi serializer (#171)
* feat!: update rpc and openapi serializer * fix types * update bracket notation * update bracket notation
1 parent 0d235c8 commit 7e904b4

27 files changed

+827
-1162
lines changed

apps/content/docs/advanced/rpc-protocol.md

Lines changed: 100 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,51 @@ description: Learn about the RPC protocol used by RPCHandler.
55

66
# RPC Protocol
77

8-
The RPC protocol enables remote procedure calls over HTTP using JSON, supporting native data types. It is utilized by [RPCHandler](/docs/rpc-handler).
8+
The RPC protocol enables remote procedure calls over HTTP using JSON, supporting native data types. It is used by [RPCHandler](/docs/rpc-handler).
99

10-
## Request
10+
## Routing
1111

12-
### Example using POST
12+
The procedure to call is determined by the `pathname`.
13+
14+
```bash
15+
curl https://example.com/rpc/planet/create
16+
```
17+
18+
This example calls the `planet.create` procedure, with `/rpc` as the prefix.
19+
20+
```ts
21+
const router = {
22+
planet: {
23+
create: os.handler(() => {}) // [!code highlight]
24+
}
25+
}
26+
```
27+
28+
## Input
29+
30+
Any HTTP method can be used. Input can be provided via URL query parameters or the request body.
31+
32+
### Input in URL Query
33+
34+
```ts
35+
const url = new URL('https://example.com/rpc/planet/create')
36+
37+
url.searchParams.append('data', JSON.stringify({
38+
json: {
39+
name: 'Earth',
40+
detached_at: '2022-01-01T00:00:00.000Z'
41+
},
42+
meta: [[1, ['detached_at']]]
43+
}))
44+
45+
const response = await fetch(url)
46+
```
47+
48+
::: info
49+
The payload can be empty (`undefined`).
50+
:::
51+
52+
### Input in Request Body
1353

1454
```bash
1555
curl -X POST https://example.com/rpc/planet/create \
@@ -19,13 +59,41 @@ curl -X POST https://example.com/rpc/planet/create \
1959
"name": "Earth",
2060
"detached_at": "2022-01-01T00:00:00.000Z"
2161
},
22-
"meta": [
23-
["detached_at", "date"]
24-
]
62+
"meta": [[1, ["detached_at"]]]
2563
}'
2664
```
2765

28-
This request targets the `create` procedure within the `planet` module. The JSON payload includes `name` and `detached_at`, where `detached_at` is flagged as a date and will be converted to a Date object upon deserialization.
66+
::: info
67+
The payload can be empty (`undefined`).
68+
:::
69+
70+
### Input with File
71+
72+
```ts
73+
const form = new FormData()
74+
75+
form.set('data', JSON.stringify({
76+
json: {
77+
name: 'Earth',
78+
thumbnail: {},
79+
images: [{}, {}]
80+
},
81+
meta: [[1, ['detached_at']]],
82+
maps: [['images', 0], ['images', 1]]
83+
}))
84+
85+
form.set('0', new Blob([''], { type: 'image/png' }))
86+
form.set('1', new Blob([''], { type: 'image/png' }))
87+
88+
const response = await fetch('https://example.com/rpc/planet/create', {
89+
method: 'POST',
90+
body: form
91+
})
92+
```
93+
94+
::: info
95+
The input can be empty (`undefined`) or binary data (`blob/file`).
96+
:::
2997

3098
## Success Response
3199

@@ -39,19 +107,20 @@ Content-Type: application/json
39107
"name": "Earth",
40108
"detached_at": "2022-01-01T00:00:00.000Z"
41109
},
42-
"meta": [
43-
["id", "bigint"],
44-
["detached_at", "date"]
45-
]
110+
"meta": [[0, ["id"]], [1, ["detached_at"]]]
46111
}
47112
```
48113

49-
A success response has an HTTP status code between 200 and 299 and returns the procedure's output.
114+
A success response has an HTTP status code between `200-299` and returns the procedure's output.
115+
116+
::: info
117+
The payload can be empty (`undefined`) or binary data (`blob/file`).
118+
:::
50119

51120
## Error Response
52121

53122
```http
54-
HTTP/1.1 400 Bad Request
123+
HTTP/1.1 500 Internal Server Error
55124
Content-Type: application/json
56125
57126
{
@@ -66,64 +135,28 @@ Content-Type: application/json
66135
}
67136
```
68137

69-
An error response uses an HTTP status code between 400 and 599 and returns an `ORPCError` object.
138+
An error response has an HTTP status code between `400-599` and returns an `ORPCError` object.
70139

71-
## Request Methods
140+
## Meta
72141

73-
Although the examples above use the `POST` method, the RPC protocol is method-agnostic. You can use any HTTP method. For example, here’s how to use a `GET` request with input in the URL:
74-
75-
```ts
76-
const url = new URL('https://example.com/rpc/planet/create')
142+
The `meta` field describes native data in the format `[type: number, path: (string | number)[]]`.
77143

78-
url.searchParams.append('data', JSON.stringify({
79-
json: {
80-
name: 'Earth',
81-
detached_at: '2022-01-01T00:00:00.000Z'
82-
},
83-
meta: [
84-
['detached_at', 'date']
85-
]
86-
}))
144+
- **type**: Data type (see [Supported Types](#supported-types)).
145+
- **path**: Path to the data inside `json`.
87146

88-
const response = await fetch(url)
89-
```
147+
### Supported Types
90148

91-
## File Upload/Download
149+
| Type | Description |
150+
| ---- | ----------- |
151+
| 0 | bigint |
152+
| 1 | date |
153+
| 2 | nan |
154+
| 3 | undefined |
155+
| 4 | url |
156+
| 5 | regexp |
157+
| 6 | set |
158+
| 7 | map |
92159

93-
When the payload includes files or blobs, it is sent as a `FormData` object with `data` and `maps` fields. In the `data` object, file placeholders appear as empty objects `{}`. The `maps` array maps file keys in the `FormData` to their corresponding paths in the `data` object.
160+
## Maps
94161

95-
```ts
96-
const form = new FormData()
97-
98-
form.set('data', JSON.stringify({
99-
json: {
100-
name: 'Earth',
101-
detached_at: '2022-01-01T00:00:00.000Z',
102-
thumbnail: {},
103-
images: [{}, {}]
104-
},
105-
meta: [
106-
['detached_at', 'date']
107-
]
108-
}))
109-
110-
form.set('maps', JSON.stringify([
111-
['json', 'thumbnail'],
112-
['json', 'images', '0'],
113-
['json', 'images', '1']
114-
]))
115-
116-
form.set('0', new Blob([''], { type: 'image/png' }))
117-
form.set('1', new Blob([''], { type: 'image/png' }))
118-
119-
const response = await fetch('https://example.com/rpc/planet/create', {
120-
method: 'POST',
121-
body: form
122-
})
123-
```
124-
125-
## Details
126-
127-
:::info
128-
TODO
129-
:::
162+
The `maps` field is used with `FormData` to map a file or blob to a specific path in `json`.

apps/content/docs/openapi/bracket-notation.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ Bracket Notation encodes structured data in formats with limited syntax, like UR
99

1010
## Usage
1111

12-
- Append `[]` to denote an array.
13-
- Append `[number]` to specify an array index (missing indexes are filled with `null`).
12+
- Append `[]` **at the end** to denote an array.
13+
- Append `[number]` to specify an array index (missing indexes create sparse arrays).
1414
- Append `[key]` to denote an object property.
1515

1616
## Limitations

0 commit comments

Comments
 (0)