|
1 | | -# JSON-Server |
| 1 | +# JSON Server v1 (Beta) |
2 | 2 |
|
3 | | -[](https://github.com/typicode/json-server/actions/workflows/node.js.yml) |
| 3 | +Fast mock REST API from a JSON file. |
4 | 4 |
|
5 | | -> [!IMPORTANT] |
6 | | -> Viewing beta v1 documentation – usable but expect breaking changes. For stable version, see [here](https://github.com/typicode/json-server/tree/v0.17.4) |
| 5 | +> Beta note: v1 can still change. For stable v0.17 docs, see: |
| 6 | +> https://github.com/typicode/json-server/tree/v0.17.4 |
7 | 7 |
|
8 | | -> [!NOTE] |
9 | | -> Using React ⚛️ and tired of CSS-in-JS? See [MistCSS](https://github.com/typicode/mistcss) 👀 |
| 8 | +## Quickstart (30s) |
10 | 9 |
|
11 | | -## Install |
| 10 | +Install: |
12 | 11 |
|
13 | | -```shell |
| 12 | +```sh |
14 | 13 | npm install json-server |
15 | 14 | ``` |
16 | 15 |
|
17 | | -## Usage |
18 | | - |
19 | | -Create a `db.json` or `db.json5` file |
| 16 | +Create `db.json`: |
20 | 17 |
|
21 | 18 | ```json |
22 | 19 | { |
23 | | - "$schema": "./node_modules/json-server/schema.json", |
24 | 20 | "posts": [ |
25 | | - { "id": "1", "title": "a title", "views": 100 }, |
26 | | - { "id": "2", "title": "another title", "views": 200 } |
27 | | - ], |
28 | | - "comments": [ |
29 | | - { "id": "1", "text": "a comment about post 1", "postId": "1" }, |
30 | | - { "id": "2", "text": "another comment about post 1", "postId": "1" } |
| 21 | + { "id": "1", "title": "Hello", "views": 100 }, |
| 22 | + { "id": "2", "title": "World", "views": 200 } |
31 | 23 | ], |
32 | | - "profile": { |
33 | | - "name": "typicode" |
34 | | - } |
| 24 | + "comments": [{ "id": "1", "text": "Nice", "postId": "1" }], |
| 25 | + "profile": { "name": "typicode" } |
35 | 26 | } |
36 | 27 | ``` |
37 | 28 |
|
38 | | -<details> |
| 29 | +Run: |
39 | 30 |
|
40 | | -<summary>View db.json5 example</summary> |
41 | | - |
42 | | -```json5 |
43 | | -{ |
44 | | - posts: [ |
45 | | - { id: "1", title: "a title", views: 100 }, |
46 | | - { id: "2", title: "another title", views: 200 }, |
47 | | - ], |
48 | | - comments: [ |
49 | | - { id: "1", text: "a comment about post 1", postId: "1" }, |
50 | | - { id: "2", text: "another comment about post 1", postId: "1" }, |
51 | | - ], |
52 | | - profile: { |
53 | | - name: "typicode", |
54 | | - }, |
55 | | -} |
| 31 | +```sh |
| 32 | +npx json-server db.json |
56 | 33 | ``` |
57 | 34 |
|
58 | | -You can read more about JSON5 format [here](https://github.com/json5/json5). |
| 35 | +Try: |
59 | 36 |
|
60 | | -</details> |
61 | | - |
62 | | -Pass it to JSON Server CLI |
63 | | - |
64 | | -```shell |
65 | | -$ npx json-server db.json |
| 37 | +```sh |
| 38 | +curl http://localhost:3000/posts/1 |
66 | 39 | ``` |
67 | 40 |
|
68 | | -Get a REST API |
| 41 | +Response: |
69 | 42 |
|
70 | | -```shell |
71 | | -$ curl http://localhost:3000/posts/1 |
| 43 | +```json |
72 | 44 | { |
73 | 45 | "id": "1", |
74 | | - "title": "a title", |
| 46 | + "title": "Hello", |
75 | 47 | "views": 100 |
76 | 48 | } |
77 | 49 | ``` |
78 | 50 |
|
79 | | -Run `json-server --help` for a list of options |
80 | | - |
81 | | -## Sponsors ✨ |
82 | | - |
83 | | -### Gold |
84 | | - |
85 | | -| | |
86 | | -| :--------------------------------------------------------------------------------------------------------------------------------------------------------: | |
87 | | -| <a href="https://mockend.com/" target="_blank"><img src="https://jsonplaceholder.typicode.com/mockend.svg" height="100px"></a> | |
88 | | -| <a href="https://zuplo.link/json-server-gh"><img src="https://github.com/user-attachments/assets/adfee31f-a8b6-4684-9a9b-af4f03ac5b75" height="100px"></a> | |
89 | | -| <a href="https://www.mintlify.com/"><img src="https://github.com/user-attachments/assets/bcc8cc48-b2d9-4577-8939-1eb4196b7cc5" height="100px"></a> | |
90 | | - |
91 | | -### Silver |
92 | | - |
93 | | -| | |
94 | | -| :-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | |
95 | | -| <a href="https://requestly.com?utm_source=githubsponsor&utm_medium=jsonserver&utm_campaign=jsonserver"><img src="https://github.com/user-attachments/assets/f7e7b3cf-97e2-46b8-81c8-cb3992662a1c" style="height:70px; width:auto;"></a> | |
| 51 | +## Query capabilities overview |
96 | 52 |
|
97 | | -### Bronze |
98 | | - |
99 | | -| | | |
100 | | -| :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------: | |
101 | | -| <a href="https://www.storyblok.com/" target="_blank"><img src="https://github.com/typicode/json-server/assets/5502029/c6b10674-4ada-4616-91b8-59d30046b45a" height="35px"></a> | <a href="https://betterstack.com/" target="_blank"><img src="https://github.com/typicode/json-server/assets/5502029/44679f8f-9671-470d-b77e-26d90b90cbdc" height="35px"></a> | |
102 | | - |
103 | | -[Become a sponsor and have your company logo here](https://github.com/users/typicode/sponsorship) |
104 | | - |
105 | | -## Sponsorware |
106 | | - |
107 | | -> [!NOTE] |
108 | | -> This project uses the [Fair Source License](https://fair.io/). Only organizations with 3+ users are kindly asked to contribute a small amount through sponsorship [sponsor](https://github.com/sponsors/typicode) for usage. **This license helps keep the project sustainable and healthy, benefiting everyone.** |
109 | | -> |
110 | | -> For more information, FAQs, and the rationale behind this, visit [https://fair.io/](https://fair.io/). |
| 53 | +```http |
| 54 | +GET /posts?views:gt=100 |
| 55 | +GET /posts?_sort=-views |
| 56 | +GET /posts?_page=1&_per_page=10 |
| 57 | +GET /posts?_embed=comments |
| 58 | +GET /posts?_where={"or":[{"views":{"gt":100}},{"title":{"eq":"Hello"}}]} |
| 59 | +``` |
111 | 60 |
|
112 | 61 | ## Routes |
113 | 62 |
|
114 | | -Based on the example `db.json`, you'll get the following routes: |
| 63 | +For array resources (`posts`, `comments`): |
115 | 64 |
|
116 | | -``` |
| 65 | +```text |
117 | 66 | GET /posts |
118 | 67 | GET /posts/:id |
119 | 68 | POST /posts |
120 | 69 | PUT /posts/:id |
121 | 70 | PATCH /posts/:id |
122 | 71 | DELETE /posts/:id |
123 | | -
|
124 | | -# Same for comments |
125 | 72 | ``` |
126 | 73 |
|
127 | | -``` |
| 74 | +For object resources (`profile`): |
| 75 | + |
| 76 | +```text |
128 | 77 | GET /profile |
129 | 78 | PUT /profile |
130 | 79 | PATCH /profile |
131 | 80 | ``` |
132 | 81 |
|
133 | | -## Params |
| 82 | +## Query params |
134 | 83 |
|
135 | 84 | ### Conditions |
136 | 85 |
|
137 | | -- ` ` → `==` |
138 | | -- `lt` → `<` |
139 | | -- `lte` → `<=` |
140 | | -- `gt` → `>` |
141 | | -- `gte` → `>=` |
142 | | -- `ne` → `!=` |
| 86 | +Use `field:operator=value`. |
143 | 87 |
|
144 | | -``` |
145 | | -GET /posts?views_gt=9000 |
146 | | -``` |
| 88 | +Operators: |
147 | 89 |
|
148 | | -### Range |
| 90 | +- no operator -> `eq` (equal) |
| 91 | +- `lt` less than, `lte` less than or equal |
| 92 | +- `gt` greater than, `gte` greater than or equal |
| 93 | +- `eq` equal, `ne` not equal |
149 | 94 |
|
150 | | -- `start` |
151 | | -- `end` |
152 | | -- `limit` |
| 95 | +Examples: |
153 | 96 |
|
154 | | -``` |
155 | | -GET /posts?_start=10&_end=20 |
156 | | -GET /posts?_start=10&_limit=10 |
157 | | -``` |
158 | | - |
159 | | -### Paginate |
160 | | - |
161 | | -- `page` |
162 | | -- `per_page` (default = 10) |
163 | | - |
164 | | -``` |
165 | | -GET /posts?_page=1&_per_page=25 |
| 97 | +```http |
| 98 | +GET /posts?views:gt=100 |
| 99 | +GET /posts?title:eq=Hello |
| 100 | +GET /posts?author.name:eq=typicode |
166 | 101 | ``` |
167 | 102 |
|
168 | 103 | ### Sort |
169 | 104 |
|
170 | | -- `_sort=f1,f2` |
171 | | - |
172 | | -``` |
173 | | -GET /posts?_sort=id,-views |
| 105 | +```http |
| 106 | +GET /posts?_sort=title |
| 107 | +GET /posts?_sort=-views |
| 108 | +GET /posts?_sort=author.name,-views |
174 | 109 | ``` |
175 | 110 |
|
176 | | -### Nested and array fields |
| 111 | +### Pagination |
177 | 112 |
|
178 | | -- `x.y.z...` |
179 | | -- `x.y.z[i]...` |
180 | | - |
181 | | -``` |
182 | | -GET /foo?a.b=bar |
183 | | -GET /foo?x.y_lt=100 |
184 | | -GET /foo?arr[0]=bar |
| 113 | +```http |
| 114 | +GET /posts?_page=1&_per_page=25 |
185 | 115 | ``` |
186 | 116 |
|
| 117 | +- `_per_page` default is `10` |
| 118 | +- invalid page/per_page values are normalized |
| 119 | + |
187 | 120 | ### Embed |
188 | 121 |
|
189 | | -``` |
| 122 | +```http |
190 | 123 | GET /posts?_embed=comments |
191 | 124 | GET /comments?_embed=post |
192 | 125 | ``` |
193 | 126 |
|
194 | | -## Delete |
| 127 | +### Complex filter with `_where` |
| 128 | + |
| 129 | +`_where` accepts a JSON object and overrides normal query params when valid. |
195 | 130 |
|
| 131 | +```http |
| 132 | +GET /posts?_where={"or":[{"views":{"gt":100}},{"author":{"name":{"lt":"m"}}}]} |
196 | 133 | ``` |
197 | | -DELETE /posts/1 |
| 134 | + |
| 135 | +## Delete dependents |
| 136 | + |
| 137 | +```http |
198 | 138 | DELETE /posts/1?_dependent=comments |
199 | 139 | ``` |
200 | 140 |
|
201 | | -## Serving static files |
| 141 | +## Static files |
202 | 142 |
|
203 | | -If you create a `./public` directory, JSON Server will serve its content in addition to the REST API. |
| 143 | +JSON Server serves `./public` automatically. |
204 | 144 |
|
205 | | -You can also add custom directories using `-s/--static` option. |
| 145 | +Add more static dirs: |
206 | 146 |
|
207 | 147 | ```sh |
208 | 148 | json-server -s ./static |
209 | 149 | json-server -s ./static -s ./node_modules |
210 | 150 | ``` |
211 | 151 |
|
212 | | -## Notable differences with v0.17 |
| 152 | +## Behavior notes |
213 | 153 |
|
214 | | -- `id` is always a string and will be generated for you if missing |
215 | | -- use `_per_page` with `_page` instead of `_limit`for pagination |
216 | | -- use Chrome's `Network tab > throtling` to delay requests instead of `--delay` CLI option |
| 154 | +- `id` is always a string and is generated if missing. |
| 155 | +- `_where` has priority over URL filter params. |
| 156 | +- Unknown operators in URL/query filters are ignored. |
0 commit comments