Every "large" project gets to a point where some routes aren't totally RESTful. It happens. But it's not great advice to say that non-RESTful routes are always a code smell.
Every "large" project gets to a point where some routes aren't totally RESTful. It happens. But it's not great advice to say that non-RESTful routes are always a code smell.
Create: POST /resources (or PUT /resources/42)
Read: GET /resources/42
Update: PUT /resources/42 (or PATCH /resources/42)
Delete: DELETE /resources/42
List/Search: GET /resourcesHTTP verbs are the operations you wish to perform. GET on a "/" resource is effectively a listing, GET on "/identifier" retrieves a specific item. PUT updates, POST creates new, DELETE is obvious. SOAP was a bad idea because it stuffed an extra RPC layer on top of HTTP's existing layer, requiring you to parse the body to find the content. Thus almost anything interacting with SOAP had to understand both HTTP and SOAP, plain HTTP tools were useless.
HTTP provides out-of-band signaling and extensions with headers. It also has a built-in mechanism to negotiate wire and content formats with Accept/Content-type. All of this means it automatically supports graceful degradation and backwards-compatibility. HTTP is stateless so unless you go out of your way to break that property it scales really well.
URIs identify the resource you want to perform the operation on. Items that are children are located "under" their parents: "/parent/42/childtype/child_id". Again - why introduce some extra system for describing these relationships and identifying resources when URIs already do a fine job of that?
If you want to take it even further you can use URIs in your data types. For example if a child needs to indicate its parent you can provide the parent URI (just the path/query/fragment portion) rather than a parent identifier. Why should the client care how you generate identifiers? It also means you can change them in the future (e.g. Int to String). Hide implementation details of the server from clients when possible.
Use Cmd/Qrys from CQRS, route to a single endpoint in a restful fashion, and spend more time doing instead of writing boilerplate.