Live data from Hacker News

Best practices for REST API design (2020)

stackoverflow.blog

71–80 of 273 posts

Re: Best practices for REST API design (2020)

#71
post #65

Do not use a page argument for pagination. If you have another process/client concurrently adding/removing items, then some items will be returned twice, and others will never be returned. It is better to use, for example, the ID of the last returned item as a starting point for the next query.

As a user I expect that to happen. Cursors on the other hand are awful for getting to arbitrary pages, they are mostly useful for "More" links as on HN or Reddit.

It's a trade-off.

Re: Best practices for REST API design (2020)

#72

Earlier quoted context omitted.

no, what im saying is graphql is introducing something they think is novel, when it already can be done in REST. it's not hard. In my specific case, using Flask-Marshmallow i can do this ``` some_resource = Resource.find_by_id(resource_id) arg = request.args.get('type_of_resource') if arg == 'with_commments': return full_resource_schema.dump(some_resource), 200 if arg == 'no_comments': return no_comments_schema.dump(…

The whole point of graphQL is to allow FE teams to decide what information they need in an organizationally decoupled fashion, you haven't done that at all. Suppose FE wants another join on that object, now they must wait for you to push more code enabling those queries.

Unfortunately for graphql, the claim that backend teams need to be constantly making endpoints for other decoupled teams is not as drastic and critical as you consider it to be.

Dare i even say switching to graphql and onboarding developers to graphql is a much more resource intensive process than adding another endpoint (or a couple).

Re: Best practices for REST API design (2020)

#73

> Then if we try to submit the payload with the email value that already exists in users, we’ll get a 400 response status code with a 'User already exists' message to let users know that the user already exists. With that information, the user can correct the action by changing the email to something that doesn’t exist. I was always under the impression that 409 would be the "correct" code here, while you'd use 400 i…

Ironically, your comment is a perfect illustration of one of the problems with REST - its tendency to provoke discussion about things that don't actually matter in practice. No user cares whether an error response came back with a 400 or a 409 status, or what those codes even mean. It's madness that as a profession we spend so much of our employers' time and money on trivial things that deliver no value whatsoever. R…

REST doesn't have any monopoly on bikeshedding.

That said, some of the practices (like being overly clever with status codes) are pointless while others are actually helpful design patterns.

Using nouns over verbs helps you fully think through the process of mutating state in a RESTful/stateless way. The HTTP verbs all have a unique purpose you should understand.

Does it always matter what size of hammer you use? No. That doesn't mean its smart to use a screwdriver as a chisel.

Re: Best practices for REST API design (2020)

#74

Design is hard. In the given example we work with an Article domain. Where there are Comments. Fine and totally fair. But how would you design your object graph from the bottom up? Articles and Comments is a fairly simple example. Imagine a Transaction in bank domain context. Would you have an endpoint like so? transactions/:id/acoount/:id Or perhaps transactions/:id account/:id/transactions Whatever you pick you mus…

REST doesn’t really have the concept of endpoints. That’s a hierarchy some people artificially impose over the top of a REST system. REST doesn’t require it. All of your URLs could be randomised and a REST system would work exactly the same.

You don’t need hierarchy in your URLs. If you want to load a transaction, then /transactions/123 is fine. If you want to load an account, then /accounts/456 is fine. You don’t need to put one under the other.

In a REST API, the primary key for a resource is the URL. If you have the primary key, URL hierarchy is unnecessary. Just use whatever is clearest for a developer to identify at a glance for debugging purposes. It’s not required by the tech.

Re: Best practices for REST API design (2020)

#75
post #70

Earlier quoted context omitted.

no, what im saying is graphql is introducing something they think is novel, when it already can be done in REST. it's not hard. In my specific case, using Flask-Marshmallow i can do this ``` some_resource = Resource.find_by_id(resource_id) arg = request.args.get('type_of_resource') if arg == 'with_commments': return full_resource_schema.dump(some_resource), 200 if arg == 'no_comments': return no_comments_schema.dump(…

Unless I’m missing something, the response schema will have an optional “comments” field whether the “with_comments” arg is passed or not.

it's just a hit to the db.

Graphql works the same way if i'm not mistaken.

and if its the case that you don't want the comments at all, then in the conditionals write your sql statements

if you want comments

select * from resource where id=some resource id

if you don't

select without comments from resource where id=some resource id

there's no need to get into specifics, the point is graphql is not bringing anything novel. everything it claims to do can be implemented in RESt if you're willing to implement it.

Re: Best practices for REST API design (2020)

#76

Earlier quoted context omitted.

> It’s the #1 reason why graphql is so popular. You only fetch what you want. It's certainly one of the main sales points for graphql. On the flip side, I've never been frustrated by getting too many fields back from an API. I suppose if I was developing exclusively in extremely bandwidth limited contexts where getting back only 2 fields rather than 50 actually made a difference, I might care. It just seems like such…

It's likely more of an issue if you're wanting to fetch lots of nested data in one request, but only a few specific fields of what could be an extremely large object, like say the just the names and profile picture URIs for a large set of users that have interacted with the object your fetching. This is particularly relevant to social media, such as Facebook.

For the cases we've hit, it made sense to do a more specialized endpoint (or media type) than to create a universal way to let clients pick that fields they want.

This works way nicer with caches and APIs where the URI is a first class citizen.

Re: Best practices for REST API design (2020)

#77

Earlier quoted context omitted.

> No user cares whether an error response came back with a 400 or a 409 status Unless your product is itself an API, your users shouldn't be exposed to its status codes. Sorry for dispensing trite advice, but you should really have a nice client between API and users, that can translate the difference between 400 and 409 statuses in a comprehensible and friendly way. :)

That's the purpose of an error message isn't it? I'm not sure what an HTTP response code is adding to that. In my experience, in any situation where you produce an API where you want the client to pay close attention to the actual error that occurred, the list of official HTTP response codes is generally woefully inadequate for the task and you're going to want to work with something much more specific. If my payment…

Let me get this straight, you don't think codes matter, but you want to manage a giant proptietary list of codes?

Won't you just send up in those huge discussions you waste so much time on?

Re: Best practices for REST API design (2020)

#78

> Then if we try to submit the payload with the email value that already exists in users, we’ll get a 400 response status code with a 'User already exists' message to let users know that the user already exists. With that information, the user can correct the action by changing the email to something that doesn’t exist. I was always under the impression that 409 would be the "correct" code here, while you'd use 400 i…

Ironically, your comment is a perfect illustration of one of the problems with REST - its tendency to provoke discussion about things that don't actually matter in practice. No user cares whether an error response came back with a 400 or a 409 status, or what those codes even mean. It's madness that as a profession we spend so much of our employers' time and money on trivial things that deliver no value whatsoever. R…

I have been bitten by this really bad idea of reusing HTTP CODE for application problems. The server was 404 itself instead of the application.

It is a bad engineering idea to reuse HTTP codes that can be thrown by multiple intermediaries confusing the client code.

Re: Best practices for REST API design (2020)

#79
post #71
post #65

Do not use a page argument for pagination. If you have another process/client concurrently adding/removing items, then some items will be returned twice, and others will never be returned. It is better to use, for example, the ID of the last returned item as a starting point for the next query.

As a user I expect that to happen. Cursors on the other hand are awful for getting to arbitrary pages, they are mostly useful for "More" links as on HN or Reddit. It's a trade-off.

Cursors are also the only reliable option for supporting programatic usage for automation use cases.

Re: Best practices for REST API design (2020)

#80
post #57

Earlier quoted context omitted.

gRPC is also a 300lb gorilla of a framework for communication and has huge problems with versioning if you aren't "running at HEAD".

My original comment might have given the impression that I was some gRPC guru when in reality I’ve only played with it very briefly. What are the versioning problems with it? I was under the impression that it was actually designed from the start to be fairly flexible with regards to changing API methods etc

Well I wasn't referring to API versioning, I was referring to the actual lib versioning. All of Google runs basically at HEAD and nearly all of their libraries reflect this. In a distributed system, if you update one of the GRPc library versions, you need to update all of them otherwise you can run into weird failures.
Post reply on HN