14

I'm working on an API (along with an SPA) for a private project and I can't decide between two route naming conventions.

Suppose I have three tables in my database : Users, Products and Orders. If I want users to be able to order products, which one of the following conventions should I follow?

  1. POST /orders with body { "product": 1 }
  2. POST /products/{id}/order

Note : In both case the user would be inferred based on the access token provided.

To me, the main difference between the two solutions above resides in the type of interface to expose to the front-end developer : do I expose routes to resources (solution 1) or to actions to be performed (solution 2)?

Are there actual (dis)avantages to use one method over the other or is it just a matter of personal taste?

Correct me if I'm wrong, but from my understanding solution 1 is REST ("create this resource") while solution 2 isn't ("perform this action").

Also, with solution 1 each route would directly map to a table in my database and some people say it's a bad idea cause external developers can then infer the database's schema based on the API routes but honestly I don't see how it's a problem.

OneCricketeer
  • 179,855
  • 19
  • 132
  • 245
Mickäel A.
  • 9,012
  • 5
  • 54
  • 71

2 Answers2

14

TL;DR

Based on my researches and on GitHub and Instagram APIs' endpoints, for a user to order a product what makes the most sense is to expose POST /users/123/orders {"product": 456} instead of POST /orders {"product": 456, "user": 123}. The idea here is to think about the context of a resource if there's one.

Sources

Best Practices for Designing a Pragmatic RESTful API

Notice that we don't need to use the 'update' verb phrase in the URL because we can rely on the HTTP verb to inform that operation. Just to clarify, the following resource URL is redundant:

PUT http://api.example.com/customers/12345/update

With both PUT and 'update' in the request, we're offering to confuse our service consumers! Is 'update' the resource?

10 Best Practices for Better RESTful API

4. Use sub-resources for relations

If a resource is related to another resource use subresources.

GET /cars/711/drivers/ Returns a list of drivers for car 711
GET /cars/711/drivers/4 Returns driver #4 for car 711

GitHub and Instagram APIs

GitHub and Instagram APIs seem to work this way too, that is to use the context of a resource when it's relevant.

For example if you want to get a list of a user's organizations using GitHub's API you'll use GET /users/flawyte/orgs and not GET /orgs {"username": "flawyte"}.

Same with Instagram's API if you want to like a media : POST /media/{media_id}/likes.

Mickäel A.
  • 9,012
  • 5
  • 54
  • 71
1

Are there actual (dis)avantages to use one method over the other or is it just a matter of personal taste?

Choice of spelling is primarily taste and convention. From the point of view of the client, both of these are opaque URI that can be used to follow your protocol. The spelling conventions are for human readers, and to make things easier on your implementation of the endpoints.

Correct me if I'm wrong, but from my understanding solution 1 is REST ("create this resource") while solution 2 isn't ("perform this action").

No, but that's a common misconception.

The REST architectural style is much more interested in questions like "how does the client know which uri to follow" and "how does the client know what media type should be used in the payload" than it is in spelling.

Where you may want to have some care is that the URI identify your resources, not the domain model entities your resource happens to communicate with.

Also, with solution 1 each route would directly map to a table in my database and some people say it's a bad idea cause external developers can then infer the database's schema based on the API routes but honestly I don't see how it's a problem.

Other way around - when you want to revise your schema, do you intend that all of the clients should have to be rewritten? Or are you instead intending that the clients be decoupled from the implementation details of the domain?

Think adapter pattern from Gang of Four -- you give your clients a well designed, stable, api that they can communicate with, and an the implementation of your resources you adapt the requests you get to the current implementation of your model.

Fielding, 2008

REST is software design on the scale of decades: every detail is intended to promote software longevity and independent evolution.

Remember: if those properties aren't important to you, if they don't support your current value proposition, then you need to trade in those constraints for something more suitable.

VoiceOfUnreason
  • 52,766
  • 5
  • 49
  • 91