├── Procfile
├── .gitignore
├── .gitattributes
├── .travis.yml
├── .github
├── FUNDING.yml
└── build.js
├── public
├── favicon.ico
├── become_a_patron_button.png
├── style.css
├── guide.html
└── index.html
├── index.js
├── CHANGELOG.md
├── src
└── app.js
├── test
└── app.js
├── LICENSE
├── package.json
├── README.md
├── seed.js
└── templates
├── GUIDE.md
├── layout.html
└── index.html
/Procfile:
--------------------------------------------------------------------------------
1 | web: node index.js
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | **/*.log
--------------------------------------------------------------------------------
/.gitattributes:
--------------------------------------------------------------------------------
1 | public/* linguist-documentation
2 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - "7"
4 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: typicode
2 | patreon: typicode
3 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/typicode/jsonplaceholder/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/.github/build.js:
--------------------------------------------------------------------------------
1 | // Convert to markdown
2 | // use layout to
3 | // create index.html
4 | // create guide.html
5 |
--------------------------------------------------------------------------------
/public/become_a_patron_button.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/typicode/jsonplaceholder/HEAD/public/become_a_patron_button.png
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | const app = require('./src/app')
2 | const port = process.env.PORT || 3000
3 |
4 | app.listen(port, () => {
5 | console.log('JSONPlaceholder listening on http://localhost:' + port)
6 | })
7 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # CHANGELOG
2 |
3 | ## 2018-08-16
4 |
5 | * Replace [placehold.it](http://placehold.it) (previous name) with [placeholder.com](http://placeholder.com) (new name)
6 | * Use `https` protocol for image URLs
7 |
--------------------------------------------------------------------------------
/src/app.js:
--------------------------------------------------------------------------------
1 | const jsonServer = require('json-server')
2 | const clone = require('clone')
3 | const data = require('../data.json')
4 |
5 | const app = jsonServer.create()
6 | const router = jsonServer.router(clone(data), { _isFake: true })
7 |
8 | app.use((req, res, next) => {
9 | if (req.path === '/') return next()
10 | router.db.setState(clone(data))
11 | next()
12 | })
13 |
14 | app.use(jsonServer.defaults({
15 | logger: process.env.NODE_ENV !== 'production'
16 | }))
17 |
18 | app.use(router)
19 |
20 | module.exports = app
21 |
--------------------------------------------------------------------------------
/test/app.js:
--------------------------------------------------------------------------------
1 | const test = require('tape')
2 | const request = require('supertest')
3 | const app = require('../src/app')
4 |
5 | test('GET /', (t) => {
6 | request(app)
7 | .get('/')
8 | .expect(200, (err) => t.end(err))
9 | })
10 |
11 | test('POST /', (t) => {
12 | const max = 10
13 | t.plan(max * 3)
14 |
15 | // Test concurrency
16 | for (var i = 0; i < max; i++) {
17 | request(app)
18 | .post('/posts')
19 | .send({ body: 'foo' })
20 | .expect(201, (err) => {
21 | t.error(err)
22 | // Check that GET /posts length still returns 100 items
23 | request(app)
24 | .get('/posts')
25 | .expect(200, (err, res) => {
26 | t.error(err)
27 | const { length } = res.body
28 | t.equal(
29 | length,
30 | 100,
31 | `more than 100 posts found (${length})`
32 | )
33 | })
34 | })
35 | }
36 | })
37 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2013 typicode
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of
6 | this software and associated documentation files (the "Software"), to deal in
7 | the Software without restriction, including without limitation the rights to
8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9 | the Software, and to permit persons to whom the Software is furnished to do so,
10 | subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jsonplaceholder",
3 | "version": "0.3.3",
4 | "description": "A simple fake REST API server for testing and prototyping.",
5 | "keywords": [
6 | "fake",
7 | "JSON",
8 | "server",
9 | "REST",
10 | "dummy",
11 | "data",
12 | "API",
13 | "testing",
14 | "prototyping"
15 | ],
16 | "homepage": "http://jsonplaceholder.typicode.com",
17 | "repository": {
18 | "type": "git",
19 | "url": "https://github.com/typicode/jsonplaceholder.git"
20 | },
21 | "scripts": {
22 | "build": "node build",
23 | "build:watch": "nodemon --watch build.js --watch templates -e js,md,html build.js",
24 | "start": "node index",
25 | "test": "node test/app"
26 | },
27 | "dependencies": {
28 | "clone": "^2.1.2",
29 | "json-server": "^0.16.0",
30 | "marked": "^0.8.0"
31 | },
32 | "devDependencies": {
33 | "Faker": "~0.7.2",
34 | "husky": "^4.2.2",
35 | "nodemon": "^2.0.2",
36 | "pupa": "^2.0.1",
37 | "rosie": "~2.0.1",
38 | "showdown": "^1.9.1",
39 | "supertest": "^4.0.2",
40 | "tape": "^4.13.0",
41 | "underscore": "~1.12.1"
42 | },
43 | "engines": {
44 | "node": "14.x"
45 | },
46 | "license": "MIT",
47 | "husky": {
48 | "hooks": {
49 | "pre-commit": "npm test"
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # JSONPlaceholder
2 |
3 | [JSONPlaceholder](https://jsonplaceholder.typicode.com) is a simple fake REST API for testing and prototyping.
4 |
5 | It's like an [image placeholder](http://placehold.it/) but for web developers.
6 |
7 | JSONPlaceholder is powered by [JSON Server](https://github.com/typicode/json-server).
8 |
9 |
10 |
11 |
12 |
13 | ## Why?
14 |
15 | Most of the time when trying a new library, hacking a prototype or following a tutorial, I found myself in need of some data.
16 |
17 | I didn't like the idea of using some public API because I had the feeling that I was spending more time registering a client and understanding a complex API than focusing on my task.
18 |
19 | But I liked the idea of image placeholders for web designers. So I decided to code a little Express server inspired by that and here is JSONPlaceholder.
20 |
21 | You can find it running here and are free to use it in your developments: https://jsonplaceholder.typicode.com.
22 |
23 | I hope you will find it useful.
24 |
25 | ## Features
26 |
27 | * No registration
28 | * Zero-config
29 | * Basic API
30 | * "Has many" relationships
31 | * Filters and nested resources
32 | * Cross-domain ([CORS](http://en.wikipedia.org/wiki/Cross-origin_resource_sharing) and [JSONP](http://en.wikipedia.org/wiki/JSONP))
33 | * Supports GET, POST, PUT, PATCH, DELETE and OPTIONS verbs
34 | * HTTP or HTTPS
35 | * Compatible with React, Angular, Vue, Ember, ...
36 |
37 | ## Guide
38 |
39 | For examples and more, you can visit https://jsonplaceholder.typicode.com
40 |
--------------------------------------------------------------------------------
/seed.js:
--------------------------------------------------------------------------------
1 | // Run this to generate data.json
2 | var fs = require('fs')
3 | var _ = require('underscore')
4 | var Factory = require('rosie').Factory
5 | var Faker = require('Faker')
6 | var db = {}
7 |
8 | // Credit http://www.paulirish.com/2009/random-hex-color-code-snippets/
9 | function hex() {
10 | return Math.floor(Math.random()*16777215).toString(16)
11 | }
12 |
13 | // Tables
14 | db.posts = []
15 | db.comments = []
16 | db.albums = []
17 | db.photos = []
18 | db.users = []
19 | db.todos = []
20 |
21 | // Factories
22 | Factory.define('post')
23 | .sequence('id')
24 | .attr('title', function() {return Faker.Lorem.sentence()})
25 | .attr('body', function() {return Faker.Lorem.sentences(4)})
26 |
27 | Factory.define('comment')
28 | .sequence('id')
29 | .attr('name', function() {return Faker.Lorem.sentence()})
30 | .attr('email', function() {return Faker.Internet.email()})
31 | .attr('body', function() {return Faker.Lorem.sentences(4)})
32 |
33 | Factory.define('album')
34 | .sequence('id')
35 | .attr('title', function() {return Faker.Lorem.sentence()})
36 |
37 | Factory.define('photo')
38 | .sequence('id')
39 | .attr('title', function() {return Faker.Lorem.sentence()})
40 | .option('color', hex())
41 | .attr('url', [ 'color' ], function(color) {
42 | return 'http://placehold.it/600/' + color
43 | })
44 | .attr('thumbnailUrl', [ 'color' ], function(color) {
45 | return 'http://placehold.it/150/' + color
46 | })
47 |
48 | Factory.define('todo')
49 | .sequence('id')
50 | .attr('title', function() {return Faker.Lorem.sentence()})
51 | .attr('completed', function() { return _.random(1) ? true : false})
52 |
53 | Factory.define('user')
54 | .sequence('id')
55 | .after(function(user) {
56 | var card = Faker.Helpers.userCard()
57 | _.each(card, function(value, key) {
58 | user[key] = value
59 | })
60 | })
61 |
62 | // Has many relationships
63 | // Users
64 | _(10).times(function () {
65 | var user = Factory.build('user')
66 | db.users.push(user)
67 |
68 | // Posts
69 | _(10).times(function() {
70 | // userId not set in create so that it appears as the last
71 | // attribute
72 | var post = Factory.build('post', {userId: user.id})
73 | db.posts.push(post)
74 |
75 | // Comments
76 | _(5).times(function () {
77 | var comment = Factory.build('comment', {postId: post.id})
78 | db.comments.push(comment)
79 | })
80 | })
81 |
82 | // Albums
83 | _(10).times(function() {
84 | var album = Factory.build('album', {userId: user.id})
85 | db.albums.push(album)
86 |
87 | // Photos
88 | _(50).times(function() {
89 | var photo = Factory.build('photo', {albumId: album.id})
90 | db.photos.push(photo)
91 | })
92 | })
93 |
94 | // Todos
95 | _(20).times(function() {
96 | var todo = Factory.build('todo', {userId: user.id})
97 | db.todos.push(todo)
98 | })
99 | })
100 |
101 | fs.writeFileSync('db.json', JSON.stringify(db, null, 2));
102 |
--------------------------------------------------------------------------------
/public/style.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: system-ui, BlinkMacSystemFont, -apple-system, Segoe UI, Roboto,
3 | Oxygen, Ubuntu, Cantarell, Fira Sans, Droid Sans, Helvetica Neue, sans-serif;
4 | color: rgba(0, 0, 0, 0.84);
5 | line-height: 1.5;
6 | }
7 |
8 | a {
9 | color: #1e87f0;
10 | text-decoration: none;
11 | border-bottom: 1px solid transparent;
12 | }
13 |
14 | div.announcement {
15 | display: block;
16 | padding: 1rem;
17 | font-weight: bold;
18 | border-width: 0;
19 | border-style: solid;
20 | border-color: currentColor;
21 | text-align: center;
22 | background: #ffe0b2;
23 | color: #e65100;
24 | }
25 |
26 | div.announcement a {
27 | color: inherit;
28 | text-decoration: underline;
29 | }
30 |
31 | div.announcement a:hover {
32 | text-decoration: none;
33 | }
34 |
35 | a:hover {
36 | text-decoration: underline;
37 | }
38 |
39 | h1 {
40 | margin: 0;
41 | font-size: 4rem;
42 | font-weight: 300;
43 | letter-spacing: 0.05em;
44 | }
45 |
46 | @media (max-width: 768px) {
47 | h1 {
48 | font-size: 2rem;
49 | }
50 | }
51 |
52 | h2 {
53 | margin-top: 6rem;
54 | margin-bottom: 1.5rem;
55 | font-size: 2rem;
56 | font-weight: normal;
57 | }
58 |
59 | header {
60 | position: sticky;
61 | top: 0;
62 | background: #ffffff;
63 | z-index: 999;
64 | }
65 |
66 | nav {
67 | margin: 0;
68 | overflow-x: auto;
69 | text-align: center;
70 | border-width: 0 0 1px 0;
71 | border-color: #e4e4e4;
72 | border-style: solid;
73 | }
74 |
75 | nav ul {
76 | display: flex;
77 | margin: 0;
78 | padding: 0;
79 | list-style: none;
80 | }
81 |
82 | nav li:first-of-type {
83 | flex-grow: 1;
84 | text-align: left;
85 | }
86 |
87 | nav li:first-of-type a {
88 | padding-left: 0;
89 | }
90 |
91 | nav li:last-of-type a {
92 | padding-right: 0;
93 | }
94 |
95 | nav li a {
96 | display: block;
97 | padding: 1.5rem;
98 | color: inherit;
99 | white-space: nowrap;
100 | }
101 |
102 | .hljs {
103 | padding: 1rem;
104 | }
105 |
106 | td:first-child {
107 | width: 8rem;
108 | }
109 |
110 | .container {
111 | max-width: 60rem;
112 | margin: auto;
113 | padding: 0 1rem;
114 | }
115 |
116 | .hero {
117 | padding: 6rem 0;
118 | text-align: center;
119 | }
120 |
121 | .sponsors {
122 | margin-bottom: 2rem;
123 | padding: 6rem 0;
124 | border-width: 1px 0;
125 | border-style: solid;
126 | border-color: #e4e4e4;
127 | text-align: center;
128 | }
129 |
130 | .sponsors h3 {
131 | font-size: 1.5rem;
132 | font-weight: normal;
133 | margin-top: 0;
134 | margin-bottom: 2rem;
135 | }
136 |
137 | .box {
138 | display: flex;
139 | justify-content: center;
140 | align-items: center;
141 | width: 20rem;
142 | margin: auto;
143 | border-radius: 0.2rem;
144 | border: 1px dashed currentColor;
145 | }
146 |
147 | .box a {
148 | display: inline-block;
149 | padding: 4rem;
150 | color: inherit;
151 | }
152 |
153 | .sponsors p {
154 | margin-top: 2rem;
155 | margin-bottom: 0;
156 | }
157 |
158 | main {
159 | margin-bottom: 6rem;
160 | }
161 |
162 | #run-button {
163 | padding: 0.5rem 1rem;
164 | margin-right: 1rem;
165 | border-width: 0;
166 | border-radius: 0.25rem;
167 | background-color: #1e87f0;
168 | color: white;
169 | cursor: pointer;
170 | transition: all 0.25s;
171 | }
172 |
173 | #run-message {
174 | opacity: 0;
175 | transition: all 0.25s;
176 | }
177 |
178 | pre {
179 | /* hack */
180 | background: #f8f8f8;
181 | }
182 |
183 | code {
184 | padding: 2rem !important;
185 | }
186 |
187 | ul {
188 | list-style: none;
189 | }
190 |
191 | #result {
192 | margin: 1.5rem 0 0;
193 | height: 176px;
194 | opacity: 0;
195 | transition: all 0.25s;
196 | }
197 |
198 | footer {
199 | padding: 6rem;
200 | background-color: #f8fafc;
201 | text-align: center;
202 | }
203 |
--------------------------------------------------------------------------------
/templates/GUIDE.md:
--------------------------------------------------------------------------------
1 |
9 | Fake Online REST API for Testing and Prototyping
10 |
Serving ~350M requests per month
11 |
Powered by
12 | JSON Server
13 | +
14 | LowDB
15 |
30 |
31 |
32 |
33 |
36 |
37 |
38 |
39 |
42 | Your Company Logo Here 43 |
44 |
52 | JSONPlaceholder is a free online REST API that you can use whenever you need some fake data.
53 |
It's great for tutorials, testing new libraries, sharing code examples, ...
54 |
59 | Run this code in a console or from any site: 60 |
61 | 62 |fetch('https://jsonplaceholder.typicode.com/todos/1')
63 | .then(response => response.json())
64 | .then(json => console.log(json))
65 |
66 |
67 | 68 | 69 |
70 | 71 |
72 | Congrats you've made your first call to JSONPlaceholder! 😃 🎉
73 |
74 | 75 | Tip: you can use 76 | 77 | http:// 78 | or 79 | 80 | https:// 81 | when making requests to JSONPlaceholder. 82 |
83 | 84 | 85 | 86 | 87 | 88 |90 | JSONPlaceholder comes with a set of 6 common resources: 91 |
92 | 93 || 96 | /posts 97 | | 98 |100 posts | 99 |
| 102 | /comments 103 | | 104 |500 comments | 105 |
| 108 | /albums 109 | | 110 |100 albums | 111 |
| 114 | /photos 115 | | 116 |5000 photos | 117 |
| 120 | /todos 121 | | 122 |200 todos | 123 |
| 126 | /users 127 | | 128 |10 users | 129 |
133 | Note: resources have relations. For example: 134 | posts have many 135 | comments, 136 | albums have many 137 | photos, ... see below for routes examples. 138 |
139 | 140 | 141 |143 | All HTTP methods are supported. 144 |
145 | 146 || GET | 149 |150 | /posts 151 | | 152 |
| GET | 155 |156 | /posts/1 157 | | 158 |
| GET | 161 |162 | /posts/1/comments 163 | | 164 |
| GET | 167 |168 | /comments?postId=1 169 | | 170 |
| GET | 173 |174 | /posts?userId=1 175 | | 176 |
| POST | 179 |/posts | 180 |
| PUT | 183 |/posts/1 | 184 |
| PATCH | 187 |/posts/1 | 188 |
| DELETE | 191 |/posts/1 | 192 |
197 | Note: you can view detailed examples 198 | here. 199 |
200 | 201 | 202 |212 | With My JSON Server online service and a simple GitHub repo, you can have your own online fake REST server in seconds. 213 |
214 |55 |
You can use JSONPlaceholder with any type of project that needs to get JSON data (React, Vue, Node, Rails, Swift, Android, …).
57 |Below you'll find examples using Fetch API. You can copy paste them in your browser Console to quickly test JSONPlaceholder.
58 |fetch('https://jsonplaceholder.typicode.com/posts/1')
60 | .then(response => response.json())
61 | .then(json => console.log(json))
62 |
63 | // Output
64 | {
65 | id: 1,
66 | title: '[...]',
67 | body: '[...]',
68 | userId: 1
69 | }
70 |
71 |
72 |
73 | fetch('https://jsonplaceholder.typicode.com/posts')
75 | .then(response => response.json())
76 | .then(json => console.log(json))
77 |
78 | // Output
79 | [
80 | { id: 1, title: '[...]' /* ... */ },
81 | /* ... */
82 | { id: 100, title: '[...]' /* ... */ }
83 | ]
84 |
85 | fetch('https://jsonplaceholder.typicode.com/posts', {
87 | method: 'POST',
88 | body: JSON.stringify({
89 | title: 'foo',
90 | body: 'bar',
91 | userId: 1
92 | }),
93 | headers: {
94 | "Content-type": "application/json; charset=UTF-8"
95 | }
96 | })
97 | .then(response => response.json())
98 | .then(json => console.log(json))
99 |
100 | // Output
101 | {
102 | id: 101,
103 | title: 'foo',
104 | body: 'bar',
105 | userId: 1
106 | }
107 |
108 | Important: the resource will not be really created on the server but it will be faked as if. In other words, if you try to access a post using 101 as an id, you'll get a 404 error.
109 |fetch('https://jsonplaceholder.typicode.com/posts/1', {
112 | method: 'PUT',
113 | body: JSON.stringify({
114 | id: 1,
115 | title: 'foo',
116 | body: 'bar',
117 | userId: 1
118 | }),
119 | headers: {
120 | "Content-type": "application/json; charset=UTF-8"
121 | }
122 | })
123 | .then(response => response.json())
124 | .then(json => console.log(json))
125 |
126 | // Output
127 | {
128 | id: 1,
129 | title: 'foo',
130 | body: 'bar',
131 | userId: 1
132 | }
133 |
134 | fetch('https://jsonplaceholder.typicode.com/posts/1', {
136 | method: 'PATCH',
137 | body: JSON.stringify({
138 | title: 'foo'
139 | }),
140 | headers: {
141 | "Content-type": "application/json; charset=UTF-8"
142 | }
143 | })
144 | .then(response => response.json())
145 | .then(json => console.log(json))
146 |
147 | // Output
148 | {
149 | id: 1,
150 | title: 'foo',
151 | body: '[...]',
152 | userId: 1
153 | }
154 |
155 | Important: the resource will not be really updated on the server but it will be faked as if.
156 |fetch('https://jsonplaceholder.typicode.com/posts/1', {
158 | method: 'DELETE'
159 | })
160 |
161 | Important: the resource will not be really deleted on the server but it will be faked as if.
162 |Basic filtering is supported through query parameters.
164 |// Will return all the posts that belong to the first user
165 | fetch('https://jsonplaceholder.typicode.com/posts?userId=1')
166 | .then(response => response.json())
167 | .then(json => console.log(json))
168 |
169 | One level of nested route is available.
171 |// Equivalent to /comments?postId=1
172 | fetch('https://jsonplaceholder.typicode.com/posts/1/comments')
173 | .then(response => response.json())
174 | .then(json => console.log(json))
175 |
176 | Available nested routes:
177 | 184 | 185 |
62 | Fake Online REST API for Testing and Prototyping
63 |
Serving ~350M requests per month
64 |
Powered by
65 | JSON Server
66 | +
67 | LowDB
68 |
83 |
84 |
85 |
86 |
89 |
90 |
91 |
92 |
95 | Your Company Logo Here 96 |
97 |
105 | JSONPlaceholder is a free online REST API that you can use whenever you need some fake data.
106 |
It's great for tutorials, testing new libraries, sharing code examples, ...
107 |
112 | Run this code in a console or from any site: 113 |
114 | 115 |fetch('https://jsonplaceholder.typicode.com/todos/1')
116 | .then(response => response.json())
117 | .then(json => console.log(json))
118 |
119 |
120 | 121 | 122 |
123 | 124 |
125 | Congrats you've made your first call to JSONPlaceholder! 😃 🎉
126 |
127 | 128 | Tip: you can use 129 | 130 | http:// 131 | or 132 | 133 | https:// 134 | when making requests to JSONPlaceholder. 135 |
136 | 137 | 138 | 139 | 140 | 141 |143 | JSONPlaceholder comes with a set of 6 common resources: 144 |
145 | 146 || 149 | /posts 150 | | 151 |100 posts | 152 |
| 155 | /comments 156 | | 157 |500 comments | 158 |
| 161 | /albums 162 | | 163 |100 albums | 164 |
| 167 | /photos 168 | | 169 |5000 photos | 170 |
| 173 | /todos 174 | | 175 |200 todos | 176 |
| 179 | /users 180 | | 181 |10 users | 182 |
186 | Note: resources have relations. For example: 187 | posts have many 188 | comments, 189 | albums have many 190 | photos, ... see below for routes examples. 191 |
192 | 193 | 194 |196 | All HTTP methods are supported. 197 |
198 | 199 || GET | 202 |203 | /posts 204 | | 205 |
| GET | 208 |209 | /posts/1 210 | | 211 |
| GET | 214 |215 | /posts/1/comments 216 | | 217 |
| GET | 220 |221 | /comments?postId=1 222 | | 223 |
| GET | 226 |227 | /posts?userId=1 228 | | 229 |
| POST | 232 |/posts | 233 |
| PUT | 236 |/posts/1 | 237 |
| PATCH | 240 |/posts/1 | 241 |
| DELETE | 244 |/posts/1 | 245 |
250 | Note: you can view detailed examples 251 | here. 252 |
253 | 254 | 255 |265 | With My JSON Server online service and a simple GitHub repo, you can have your own online fake REST server in seconds. 266 |
267 |