Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

URL design for an API

I'm working on a private apis for our backend.
I have collections that have associations.
Each collection can be requested, paginated, you can also ask for the associations and paginate this associations.

We're not sure about which URL design to use ... we're thinking about :

  • /users.json?per_page=10&association=parts,auditions&parts_per_page=5&auditions_per_page=5

  • /users.json?per_page=10&association[]=parts&association[]=auditions&parts_per_page=5&auditions_per_page=10

  • /users.json?per_page=10&association[auditions]=true&association[parts][per_page]=5

What do you think ? which one would you chosse ? why ? is one of this not looking like valid url schemes ?

Thanks !

like image 293
Mike Avatar asked Dec 10 '10 14:12

Mike


People also ask

How do I write an API URL?

Examples of valid server URLs: https://api.example.com. https://api.example.com:8443/v1/reports. http://localhost:3025/v1.

What is API URL structure?

The API URL is structured as follows: {tenant url}/{base api url}/{business object name}({'business object unique key'})?$ {query parameter and value}

Does an API have a URL?

An API URL Path is an address that allows you to access an API and its various features. If you've ever used a computer in your life (which I'm sure you have, since you're reading this), you should have at least some idea of what a URL is — even outside the context of APIs.

What is the URL used for with REST API?

The base URL is the internet host name for the REST API. The resource path is the address to the API resource. Query parameters are name/value pairs passed to the REST API after a ? in the endpoint URL. Query parameters pass inputs to a REST API and are often used to filter, sort, or specify the output format.


3 Answers

My answer: /users.json. HTTP is optimized for large-grain hypermedia transfer; caching is a big part of this, and none of the URI schemes given above are very cache-friendly.

Squid, for example, is a popular HTTP cache that by default will not cache any URL that has a querystring. In addition, many clients and even servers and intermediaries generate and consume query string parameters in an undefined order; that is, "?a=3&b=5" can be arbitrarily rewritten as "?b=5&a=3". However, for HTTP caching, the order matters, and the two pages will be cached separately even though they have the same content. As you add parameters, this problem increases exponentially.

You should design your resources (and their representations) to take advantage of caching by two opposing but complementary techniques:

  1. Combine fragmented and partial representations into larger, unified representations, and
  2. Separate large, unified representations into smaller representations along cache boundaries (which tend to be transactional boundaries), but related by hyperlinks.

In your case, step 1 implies combining associations and parts into the "users" representation, without any option for the client to configure which ones and how many. That will allow you to aggressively cache the single response representation without overloading your (and their) caches with a combinatorial explosion of responses due to all the querystring options.

Step 2 implies separating /users.json into separate "user" entities, each with an "associations" resource and a "parts" resource. So /users/{id} and /users/{id}/associations and /users/{id}/parts. The "/users" resource then returns an array of hyperlinks to the individual "/users/{id}" resources, and each "/users/{id}` representation contains hyperlinks to its associations and parts (that part is more malleable--it might fit your application better to embed the associations and parts into the user resource directly). That will allow you to aggressively cache the response for each "in demand" resource without having to cache your whole database.

Then your users will scream "but that's 10 times the network traffic!" To which you calmly respond, "no, that's 1/10th the network traffic, because 9 times out of 10 the requested resources are already sitting in your client-side (browser) cache (and when they're not, it's 1/10th the server's computational resources since they're sitting in a server-side cache, and when they're not there either, we avoid stampeding with a smart cache on the server)."

Of course, if the /users resource is something a million new visitors hit every day, then your optimization path might be different. But it doesn't seem so based on your example URI schemes.

like image 145
fumanchu Avatar answered Oct 03 '22 18:10

fumanchu


There are a lot of useful posts under the restful-url tag.

Some useful posts:

Do REST API URLs have to look like this?

Best practices on using URIs as parameter value in REST calls.

How to create REST URL's without verbs?

like image 26
Marcus Leon Avatar answered Oct 03 '22 18:10

Marcus Leon


I would go for the 1st one. I don't like to see the [] notation on the url, IMHO it makes harder for the client to both use and understand. A few changes as suggestions.

1) As association seems to be an array, change for associations (plural, if I am right and it is an array)

2) You can also try to put a default per_page and an optional one, even aggregating, something like per_page_parts_auditions instead of using both per_page_parts and per_page_auditions. I wouldn't do it if your API was designed to be public, since it makes easier to use but harder to understand, but as you posted it is a private one.. should be a good way to avoid replication.

like image 28
Diego Dias Avatar answered Oct 03 '22 18:10

Diego Dias