Skip to content

Instantly share code, notes, and snippets.

@jim-clark
Last active April 12, 2024 18:13
Show Gist options
  • Star 50 You must be signed in to star a gist
  • Fork 52 You must be signed in to fork a gist
  • Save jim-clark/17908763db7bd3c403e6 to your computer and use it in GitHub Desktop.
Save jim-clark/17908763db7bd3c403e6 to your computer and use it in GitHub Desktop.

RESTful Routes to CRUD Mapping

Example resource: posts

HTTP Method
(Verb)
Path/Endpoint/URI CRUD Operation Typical
Controller Action
Has Data
Payload
GET /posts Read all posts index No
GET /posts/:id Read a specific post show No
POST /posts Create a new post create Yes
PUT /posts/:id Update specified post update Yes
DELETE /posts/:id Delete specified post delete No

Additional Common Non-RESTful (CRUD-less) Routes

HTTP Method
(Verb)
Path/Endpoint/URI Purpose Typical
Controller Action
Has Data
Payload
GET /posts/new Return view (form) to add a new post new No
GET /posts/:id/edit Return view (form) to edit a post edit No

Routing for Related Resources (One:Many & Many:Many Relationships)

HTTP Method
(Verb)
Path/Endpoint/URI CRUD Operation
or Purpose
Note
GET /posts/:id/comments Read all comments for a post No payload
GET /comments/:id Read one comment for a post "Shallow" route / No payload
GET /posts/:id/comments/new n/a (Non-RESTful) OPTIONALLY display a dedicated form used to create a nested resource
POST /posts/:id/comments Create a comment for a post (1:M) Needs Payload
PUT /comments/:id Update specified comment "Shallow" route / Needs payload
DELETE /comments/:id Delete specified comment "Shallow" route / No payload
POST /posts/:postId/blogs/:blogId Associate a post with a blog (M:M) No payload
POST /posts/:postId/blogs Associate a post with a blog (M:M) id of blog included in payload vs endpoint

"Shallow routes are for CRUD operations where the parent's id is not needed. For example, you do not need the id of the post route to delete a specific comment - you only need that particular comment's id.

Most apps have data resources related to the logged in user. However, in regards to routing, DO NOT treat these data resources as nested resources. The server will already know who the logged in user is, therefore you will never need to, nor should you, provide the id of the logged in user, for example, never have a route such as POST /users/:id/posts. Instead, a route of POST /posts is sufficient for creating a post for the logged in user. This being the case, if for some reason your app's functionality calls for reading a paricular user's data that is not the logged in user, then yes, a route such as GET /users/:id/profile would be okay.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment