Search code examples
restapi-design

API routes naming convention


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.


Solution

  • 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.