Live data from Hacker News

How to (and how not to) design REST APIs

github.com

91–100 of 153 posts

Re: How to (and how not to) design REST APIs

#91
APIs with inconsistent object schemas and lacking error messages are the absolute worst. I've been spending some time working with Keycloak lately. Adding properties that look simple to add in the GUI are an absolute nightmare via API, made even worse with barely-existent documentation.

Re: How to (and how not to) design REST APIs

#92
post #46
post #38

“RESTful” API design is mostly bike-shedding. There’s no standard. Every REST API looks different. Clients have to refer to documentation anyway, so consistent URL patterns achieve nothing. People waste large amounts of time over totally inconsequential minutiae like whether to use singular or plural words in URLs. Separating idempotent calls from non-idempotent calls is useful, but REST overcomplicates this. All tha…

Agree. But I pick REST (or “json over http”) any day of the week instead of graphql, soap, grpc, etc.

You are supposed to do use those 3 through some kind of heavy tool, while it's well understood that you do rest with just an http library.

Rest is simpler, but comes at the cost of a lot of nice things like automatic endpoints generation and type verification. The problem is that the heavy tooling tends to not be there or not work correctly. But this is not a win for that kind of simplicity, that's a reason to improve the protocol design.

Re: How to (and how not to) design REST APIs

#93

Some good points - particularly about not returning arrays (I've made that mistake!) But I feel 410 instead of 404 is pretty controversial: > There are many layers of software that can return 404 to a request Anything in your stack can return any HTTP error code - I don't see why 404 is special. > When calling (say) GET /things/{thing_id} for a thing that doesn't exist, the response should indicate that 1) the server…

There are two reasons behind 404 being a bad response code to use for empty results.

- Did I get a 404 on this endpoint because the endpoint doesn't exist? Or did I get that because the object I was looking for doesn't exist? Great, I need to dig into the response body to find out, indicate that I can either get a 200 or a 404 with this endpoint, and deal with the odd case where the API returns HTML regardless of the MIME type in the Accept header if the endpoint itself is not there because "fuck you, couldn't be bothered".

- Some HTTP libraries will consider anything that's not a 1/2/3xx an error. That can be annoying to deal with.

Re: How to (and how not to) design REST APIs

#94

A missing rule is "DON'T use strings for timestamps". Which implies "Rule #6: DO use strings for all identifiers" is not good advice.

I disagree that that should be a rule. String timestamps are fine as long as you pick a common standard for the format. Preferable to Unix epoch-seconds or -millis or whatever, at least, if that's what you're suggesting instead. If you're serving over HTTP you clearly don't need the minuscule efficiency gain, and those are a pain (for a human) to read & write.

If a human is reading and certainly writing your JSON then something is wrong. Choosing a number isn't about efficiency its about correctness. A lot can go wrong when you choose a string for a timestamp.

The article references Stripe in a few places for examples of good designs. Guess what, they use numbers for timestamps. And not for performance reasons.

Re: How to (and how not to) design REST APIs

#95

Earlier quoted context omitted.

I disagree that that should be a rule. String timestamps are fine as long as you pick a common standard for the format. Preferable to Unix epoch-seconds or -millis or whatever, at least, if that's what you're suggesting instead. If you're serving over HTTP you clearly don't need the minuscule efficiency gain, and those are a pain (for a human) to read & write.

If a human is reading and certainly writing your JSON then something is wrong. Choosing a number isn't about efficiency its about correctness. A lot can go wrong when you choose a string for a timestamp. The article references Stripe in a few places for examples of good designs. Guess what, they use numbers for timestamps. And not for performance reasons.

> If a human is reading and certainly writing your JSON then something is wrong.

It just means someone’s working with it. Developing an integration, reading logs or a dump or a raw backup, troubleshooting something, et c. This happens plenty with any system that actually gets used, and not (necessarily) because something’s gone wrong. And timestamps have a way of making it into things like query strings, may not be someone writing your json by hand. Numeric timestamps are better for naïve automatic sorting/ordering, string is better for reading and writing.

Re: How to (and how not to) design REST APIs

#97

This falls down as soon as it makes a fundamental misunderstanding of what makes a REST api into a REST api. It gives this as a ‘bad’ example: GET /v3/application/shops/{shop_id}/listings/{listing_id}/properties With the justification that “The {listing_id} is globally unique; there's no reason for {shop_id} to be part of the URL. “ No the point of the API is that /v3/application/shops/{shop_id}/listings/{listing_id}…

You apparently have not actually used Etsy's API. No, the shop id is not in fact part of the globally unique identifier of an Etsy listing, and the properties are not dependent on the shop. Etsy listings have a 1:N relationship with Etsy shops. The API was a mistake, which they are slowly correcting - they've already changed: GET /v3/application/shops/{shop_id}/listings/{listing_id} to: GET /v3/application/listings/{…

You apparently haven't read Fielding's paper. Etsy isn't doing it right. If you read Fielding's paper, OP's point is correct. The whole URL is a resource.

Re: How to (and how not to) design REST APIs

#98

I’d just like to interject for a moment. What you’re referring to as REST, is in fact, JSON/RPC, or as I’ve recently taken to calling it, REST-less. JSON is not a hypermedia unto itself, but rather a plain data format made useful by out of band information as defined by swagger documentation or similar. Many computer users work with a canonical version of REST every day, without realizing it. Through a peculiar turn…

I'm on your side, but every time you say "a hypermedia" it kills me.

Re: How to (and how not to) design REST APIs

#99

Earlier quoted context omitted.

You use plurals anyway to fetch collections: GET /students So you can't escape the problem unless you want `GET /child` to fetch multiple children. Also, you should avoid verbs in URLs (IMHO, of course). You're adding to the students collection, so post to students: # BAD POST /student/create # GOOD POST /students

An API is not an essay, in OOP you write Array and not Array and yet you understand the type is about an array of students. Getting hung up on grammar in an API is probably the dumbest problem to have. If you think `GET /student` is confusing, or more importantly, structurally restrictive as an API, you can think about it as `GET /student/filter` where the "filter" may be a specific student id, or a range of ids, or…

> one of Fielding's own examples from his blog

Where?

Re: How to (and how not to) design REST APIs

#100

Earlier quoted context omitted.

You use plurals anyway to fetch collections: GET /students So you can't escape the problem unless you want `GET /child` to fetch multiple children. Also, you should avoid verbs in URLs (IMHO, of course). You're adding to the students collection, so post to students: # BAD POST /student/create # GOOD POST /students

An API is not an essay, in OOP you write Array and not Array and yet you understand the type is about an array of students. Getting hung up on grammar in an API is probably the dumbest problem to have. If you think `GET /student` is confusing, or more importantly, structurally restrictive as an API, you can think about it as `GET /student/filter` where the "filter" may be a specific student id, or a range of ids, or…

I think just about anyone who uses a name referencing an Array will give it the name "students".

And it does often end up mattering, for clarity where at its use sites where you won't have the type declaration to help you out, and for having "student" available as a name in the same scope, as it's typical to pull an item out of a collection.

/student/all looks particularly icky to me. For getting a student, it seems unlikely that we'd identify one using these words, but in other domains, they may end up conflicting with another resource. Whatever you end up doing about that, it'll surely be gross.

I think plurals are better so nyah! Heh.

Also, it's totally my job to get hung up on these kinds of details. Clarity, avoiding collisions, enabling easy expansion, and especially averting future breaking changes to deal with the aforementioned matter to others.

Post reply on HN