Communities

Writing
Writing
Codidact Meta
Codidact Meta
The Great Outdoors
The Great Outdoors
Photography & Video
Photography & Video
Scientific Speculation
Scientific Speculation
Cooking
Cooking
Electrical Engineering
Electrical Engineering
Judaism
Judaism
Languages & Linguistics
Languages & Linguistics
Software Development
Software Development
Mathematics
Mathematics
Christianity
Christianity
Code Golf
Code Golf
Music
Music
Physics
Physics
Linux Systems
Linux Systems
Power Users
Power Users
Tabletop RPGs
Tabletop RPGs
Community Proposals
Community Proposals
tag:snake search within a tag
answers:0 unanswered questions
user:xxxx search by author id
score:0.5 posts with 0.5+ score
"snake oil" exact phrase
votes:4 posts with 4+ votes
created:<1w created < 1 week ago
post_type:xxxx type of post
Search help
Notifications
Mark all as read See all your notifications »
Q&A

Welcome to Software Development on Codidact!

Will you help us build our independent community of developers helping developers? We're small and trying to grow. We welcome questions about all aspects of software development, from design to code to QA and more. Got questions? Got answers? Got code you'd like someone to review? Please join us.

Using nested paths vs. flat ones for API resources

+5
−0

This is based on a code review discussion that I had with a colleague about the way I have designed the resources paths for an ASP.NET Core controller that is currently consumed only internally (by a SPA).

The paths were flattened (e.g. GET /api/productreview/{reviewId}) and my colleague argued that they should be nested (e.g. GET /api/product/{productId}/review/{reviewId}.

My rationale for choosing the "flattened" version was the following:

  • any functionality should get the minimum required input to do its job. Any redundant information requires extra checks (i.e. what happens if reviewId does not actually belong to the productId?)

  • the endpoints are only used by our own SPA and thus only queried by the SPA and by us via the SwaggerDocs

From a REST perspective, I agreed and changed them, since the ids are integer values and we do not risk having very long URLs.

I am wondering if there is a guideline related to choosing hierarchical API paths over flattened ones based on various criteria such as the way the API is consumed and possibly other criteria.

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.
Why should this post be closed?

0 comment threads

1 answer

+6
−0

Actually, while REST mandates a great many things, it does not constrain the structure of URLs. To wit: The paper that coined the term "REST" describes resource identifiers as black boxes, and makes no reference to their internal structure. In fact, if we take a strict reading of the REST architecture, we'd have to follow the HATEOAS constraint, which implies that the structure of URLs must not matter to clients :-)

Granted, most sane people ignore the HATEOAS constraint, since that constraint is only useful when using a generic client, but your everyday angular app is specific to the API consumed. In this relaxed REST architecture, the app may have prior knowledge of URLs and their structure, but since this affects only the app, and the app is often done by a same team, this is an internal matter that does not have any deep architectural impact.

So there is nothing at all in REST that says that URLs must be nested as deeply as possible. You can express relationships by nesting, but you can also express them by links (or plain object identifies, if you don't follow HATEOAS). In fact, in general this is necessary because URLs are hierarchical, but relationships aren't necessarily tree shaped. So REST must offer both hierarchical resources, and links, and it is fine to use either of these approaches.

The one area where REST could be construed to say something about the structure of URLs is the interaction with HTTP Caching, if that matters to you. By default, a POST will invalidate the cache of the URL being posted to, but not the cache of other URLs. Therefore, the default is appropriate if each resource is available via GET under exactly one URL. For instance, extending your example, it would be rather bad form to return the same data from

/product/123/review/345/author
/product/127/review/349/author

But that's what I already hinted at: Nested paths might be ok for composition, but not for arbitrary associations.

That is, in general you'll want to use links, but you can also use nested paths if the relationship is a composition. In general, there is no technical reason to prefer one over the other, so it comes down to convenience and conveying semantics to the human calling your API.

That is, you could use a nested path to emphasize that the relationship is a composition, or to make your API easier to organize, or to secure it more easily (for instance if you use declarative access control based on URL patterns). On the other hand, it may be inconvenient for the caller to have to remember and provide the product id in addition to the review id. Barring any compelling reason, I'd default to KISS, and use the simpler URL format.

History
Why does this post require attention from curators or moderators?
You might want to add some details to your flag.

0 comment threads

Sign up to answer this question »