Live data from Hacker News

How to Design Better APIs

r.bluethl.net

171–180 of 238 posts

Re: How to Design Better APIs

#171

Something I wonder is how to design search/list endpoints where the query can be long (a list of IDs, ex: /users?ids=123e4567-e89b-12d3-a456-426614174000,123e4567-e89b-12d3-a456-426614174001,123e4567-e89b-12d3-a456-426614174002,...), so long that it can exceed the url max length (2048), after 50 UUIDs, you can quickly exceed that length, so GET is not ideal, so which method, SEARCH with a body? POST with a body?

There was a new RFC published a few months ago to address this use case. It defines a new HTTP method QUERY, which is defined to be safe & idempotent like GET and explicitly allows a request body like POST. See https://www.ietf.org/id/draft-ietf-httpbis-safe-method-w-bod...

great, thanks for the info!

Re: How to Design Better APIs

#172

Sometimes, I feel that we ought to have a simple protocol, on top of HTTP, to simply do remote procedure calls and throw out all this HTTP verbs crap. Every request is a http POST, with or without any body and the data transfer is in binary. So that objects can be passed back and forth between client and server. Sure, there is gRPC, but it requires another API specification (the proto files). There I said it. HTTP Ve…

We do, it's called JSON-RPC.

Arguably, the vast majority of REST APIs are "JSON RPC" with a more convoluted calling convention based on URLs, HTTP verbs and status codes.

Re: How to Design Better APIs

#173

Something I wonder is how to design search/list endpoints where the query can be long (a list of IDs, ex: /users?ids=123e4567-e89b-12d3-a456-426614174000,123e4567-e89b-12d3-a456-426614174001,123e4567-e89b-12d3-a456-426614174002,...), so long that it can exceed the url max length (2048), after 50 UUIDs, you can quickly exceed that length, so GET is not ideal, so which method, SEARCH with a body? POST with a body?

I would go with POST with a body in that case, where I interpret is as a "new search item" and use GET to scan through results, if there are many results available. I don't think I've needed something like this more than once or twice though. From users perspective, asking information on specific 50 items at once is not something commonly done.

it's used for an export feature, where we join data from the client-side, not ideal, but for now it's a good compromise in terms of complexity for the API and client

Re: How to Design Better APIs

#174
post #70

Can someone share how they handle versioning in their API when it comes to data model changes? For example `POST /users` now takes a required field `avatar_url` but it was not part of `v1`. Since this field is validated in the DB, merely having `v1` `v2` distinction at the API layer is not sufficient. So I was thinking we will have to either 1) disable DB validations and rely on app validations or 2) run two separate…

I really like this way of versioning https://medium.com/@XenoSnowFox/youre-thinking-about-api-ver... It uses Accept and Content-Type to version resources: application/vnd.company.article-v1+json

That's...really clever, but at the same time, I feel like there's a lot of assumptions baked into how Content-Types are used, and making your own content-type for each data model when it's all just application/json seems...wrong to me on an intuitive level, but I can't quite annunciate why.

I only half agree with the sentiment that /api/v1 violates REST patterns. I don't think there's any guarantee that /api/v1/bars/123 can't be the same object as /api/v2/bars/123.

Re: How to Design Better APIs

#175
post #2

The error messages could be better yet. The example uses a different code per issue, for instance: "user/email_required". Most integrators will build their UI to highlight the input fields that contain an error. Making them parse the `code` field (or special-case each possible code) is pretty toilsome. // from blog post { "code": "user/email_required", "message": "The parameter [email] is required." } Make it parseab…

Agreed. But rather than reinvent, let’s just use JSON API standard?

https://jsonapi.org/format/

(Scroll to the very bottom)

Re: How to Design Better APIs

#176

Sometimes, I feel that we ought to have a simple protocol, on top of HTTP, to simply do remote procedure calls and throw out all this HTTP verbs crap. Every request is a http POST, with or without any body and the data transfer is in binary. So that objects can be passed back and forth between client and server. Sure, there is gRPC, but it requires another API specification (the proto files). There I said it. HTTP Ve…

Agreed 100%. Slapping a REST api over a software is like reducing that software to a set of resources and attribute updates over those resources. And that never feels like the right way to talk with a software. That could be convenient for the majority of crud apps out there, but not everything we build is a crud system. For example how would you design operations on a cloud word processor as REST apis?

A better perspective would be, most softwares can be viewed as a set of domain specific objects and the set of operations (verbs) that can happen to those objects. These operations may not be a single attribute update, but a more complex dynamic set of updates over a variety of business objects. If you try to model this with a REST api, it either quickly becomes chatty or you end up compromising on REST principles.

GraphQL seems to make much more sense than REST, IMO.

Re: How to Design Better APIs

#177

Sometimes, I feel that we ought to have a simple protocol, on top of HTTP, to simply do remote procedure calls and throw out all this HTTP verbs crap. Every request is a http POST, with or without any body and the data transfer is in binary. So that objects can be passed back and forth between client and server. Sure, there is gRPC, but it requires another API specification (the proto files). There I said it. HTTP Ve…

I’m not sure what issue the verbs are creating, can someone help me get through my thick skull what this persons issue with them is? I don’t see how they add much complexity, just check the API docs and see what verb you need to use to perform a certain action.

Re: How to Design Better APIs

#178
post #45

Earlier quoted context omitted.

I completely disagree. I find envelopes to be unnecessary cruft that just junk up otherwise clear code. And I think packing metadata into an envelope along with the actual data keeps people from thinking clearly about their own APIs, mostly with respect to ambiguity surrounding the word “error”. Validation errors are errors and network failures are errors, but they’re very different animals and should never be confla…

Well I imagine this is why sages like uncle bob and sam newman will always be needed. > Validation errors are errors and network failures are errors, but they’re very different animals and should never be conflated. > I don’t want to check for a status code in metadata ever, when an HTTP status is provided. These seem like conflicting views. If the HTTP status is all you check you must be conflating application/opera…

I think I'm with Jack on this one, at least when it comes to REST interfaces. When I query GET /bar/123, I want an object with a Bar protocol/content-type. I don't want a Envelope[Bar]. What if it's any data type other than json-isomorphic, e.g. image or video? Is /videos/123.mp4 going to return a json object like

    {"data": , "status": "whatever"}
Of course not!

You already have an envelope, it's the HTTP protocol. The real trick is generically mapping data structures to HTTP responses with headers. In fact HTTP-response-shaped-objects make halfway decent general purpose envelopes in the business logic itself. They are basically Result[T, E] but with even more metadata available.

Re: How to Design Better APIs

#179

I’m gonna say it: Many rest apis are lazy and developer friendly, not consumer friendly. If you have related resources, let’s say, product and product options as two distinct endpoints: - /api/product - /api/options Then, and I want to be clear here, it is impossible for a client to perform an atomic operation on multiple distinct objects types. Let’s say the client needs to add a product with a single option or fail…

Generally internal APIs are developed alongside one or two apps. They don't need a pure, resource-oriented, API that perfectly represents the domain models but ignores how the API is used in practice. A good example is the tip on PUT vs PATCH to update objects. That seems to be missing the point. Why are you forcing the clients to calculate the correct resource fields to PATCH to the server? This is supposed to be an…

> Sure, HTTP only has 5 verbs

More like 40.

You can also just like...make up your own verbs, the HTTP police won't arrest you, though this rustles the jimmies of HTTP purists. No guarantees any middleware will support it, and this is probably a bad idea if you actually do this in public apis, it's more so "hey, these verbs aren't magic incantations, it's just a string which gets switch-cased".

Same with HTTP status codes. There's obviously some well known ones but you can just like...make up your own.

https://www.iana.org/assignments/http-methods/http-methods.x...

Re: How to Design Better APIs

#180
post #155

ISO 8601 is bad, use RFC 3339. A lot of implementation are actually based on an ISO draft which changed in final release. But most dev do not have access to the spec. For example, timezone can only be specified as offset in the standard, while implementations accept name. Globally avoid ISO for software, it is non free crap. Also, do not use those standard for dates with timezone in the future. Use wall time/date and…

Why use string-based timestamps at all? Use unixtime. It's much easier to parse and it literally can't be malformed.
Post reply on HN