3 ms·
I would go for the hierarchical urls, like: - /organizations/:organizationId/blogs/:blogId - /organizations/:organizationId/blogs/:blogId/sections/:sectionId
by rvdginste 4y ago
I would go for the hierarchical urls, like:
- /organizations/:organizationId/blogs/:blogId
- /organizations/:organizationId/blogs/:blogId/sections/:sectionId
- /organizations/:organizationId/blogs/:blogId/threads/:threadId/comments/:commentId
I do this because it expresses the structure and the constraints of the data. A blog cannot exist without being linked to an organisation. And then you typically have the following CRUD endpoints:
- /organizations/:organizationId/blogs, with GET and POST to retrieve a list of blogs belonging to an organization and to create a blog for an organisation
- /organizations/:organizationId/blogs/:blogId, with GET, PUT and DELETE to retrieve, update and remove a blog
The fact that you always have the :organizationId in the url likely means that you can easily verify authorization, because I assume you would have a link between the user and an organization and maybe that link would already be available in the access token.
I don't think it is a problem that the urls are heavily nested. The urls are not supposed to be manually entered, but are using from within an application. I like the use of HATEOAS links, because I don't really like the frontend trying to assemble urls by itself.
Also note that next to the hierarchical links, you might need some extra for search that are not hierarchical. For example, say that there is a need to search blogs across organizations. This could be provided using the following:
- /blogs?description=test&language=en
You can provide a search endpoint in the root for blogs. This endpoint could then return some kind of blog object with a reference to the actual blog location (like /organizations/34/blogs/11). When you use this approach, the frontend has no need to assemble urls and the structure or complexity of the url does not matter. Do note that the frontend still needs some generic "start" urls like the blogs search endpoint.
Additional advantage (like others have mentioned), is that with the hierarchical urls it becomes more difficult to "guess" an url. Altough, if you want to properly protect against that, you should transform the ids before putting them in the url and transform them back when reading them out of an incoming url, for example using symmetric encryption with a secret only known in the backend.
- adrianmsmith 4y ago> - /organizations/:organizationId/blogs, with ... POST to ... create a blog for an organisation Be careful with that! If there's a network error sending the response, the blog will have been created and you won't have received the ID on the client. In a distributed environment (such as REST) it's better to make all calls idempotent. Choose an ID on the client e.g. generate a random UUID. Then do a PUT to ..../:id. That will update the blog if it exists or create it if not. If the create call fails, you can just retry it (with the same ID), if the request previously failed and it never got created it'll create it now, and if the response previously failed and it did get created but you never got the successful response it'll get "edited" to the same values as it already has.