Everything I know about good API design
51–60 of 168 posts
Re: Everything I know about good API design
#52Earlier quoted context omitted.
I don't see any harm in adding versioning later. Let's say your api is /api/posts, then the next version is simply /api/v2/posts.
It's a problem downstream. Integrators weren't forced to include a version number for v1, so the rework overhead to use v2 will be higher than if it was present in your scheme to begin.
Re: Everything I know about good API design
#53Anyone else old enough to remember when "API" also meant something that had nothing to do with sending and receiving JSON over HTTP? In some cases, you could even make something that your users would install locally, and use without needing an Internet connection.
Re: Everything I know about good API design
#54Earlier quoted context omitted.
There are other options that allow long-lived access with naturally rotating keys without OAuth and only a tiny amount of complexity increase that can be managed by a bash script. The refresh token/bearer token combo is pretty powerful and has MUCH stronger security properties than a bare API key.
Refresh tokens are only really required if a client is accessing an API on behalf of a user. The refresh token tracks the specific user grant, and there needs to be one refresh token per user of the client. If a client is accessing an API on behalf of itself (which is a more natural fit for an API Key replacement) then we can use client_credentials with either client secret authentication or JWT bearer authentication…
There doesn't need to be any OIDC or third party involved to get all the benefits of them. The keys can't be used by multiple simultaneous clients, they naturally expire and rotate over time, and you can easily audit their use (primarily due to the last two principles).
Re: Everything I know about good API design
#55While the author doesn't seem to like version based APIs very much, I always recommend baking them in from the very start of your application. You cannot predict the future and chances are there will be some breaking change forced upon you by someone or something out of your control.
If there is a breaking change forced upon in the future, can’t we use a different name for the function?
/v1/downloadFile
/v2/downloadFile
Is much easier to check for a v3 then
/api/downloadFile
/api/downloadFileOver2gb
/api/downloadSignedFile
Etc. Etc.
Re: Everything I know about good API design
#56While the author doesn't seem to like version based APIs very much, I always recommend baking them in from the very start of your application. You cannot predict the future and chances are there will be some breaking change forced upon you by someone or something out of your control.
If there is a breaking change forced upon in the future, can’t we use a different name for the function?
Re: Everything I know about good API design
#57Earlier quoted context omitted.
otoh staticly-linked executables are incredibly stable - it's nice to have that option.
From what I understand, statically linking in GNU's libc.a without releasing source code is a violation of LGPL. Which would break maybe 95% of companies out there running proprietary software on Linux. musl libc has a more permissive licence, but I hear it performs worse than GNU libc. One can hope for LLVM libc[1] so the entire toolchain would become Clang/LLVM, from the compiler driver to the C/C++ standard librar…
But I don't think I've ever seen anybody actually do this.
Re: Everything I know about good API design
#58While the author doesn't seem to like version based APIs very much, I always recommend baking them in from the very start of your application. You cannot predict the future and chances are there will be some breaking change forced upon you by someone or something out of your control.
I have to agree with the author about not adding "v1" since it's rarely useful. What actually happens as the API grows- First, the team extends the existing endpoints as much as possible, adding new fields/options without breaking compatibility. Then, once they need to have backwards-incompatible operations, it's more likely that they will also want to revisit the endpoint naming too, so they'll just create new endpo…
This is an interesting empirical question - take the 100 most used HTTP APIs and see what they do for backward-incompatible changes and see what versions are available. Maybe an LLM could figure this out.
I've been just using the Dropbox API and it is, sure enough, on "v2". (although they save you a character in the URL by prefixing "/2/").
Interesting to see some of the choices in v1->v2,
https://www.dropbox.com/developers/reference/migration-guide
They use a spec language they developed called stone (https://github.com/dropbox/stone).
Re: Everything I know about good API design
#59Anyone else old enough to remember when "API" also meant something that had nothing to do with sending and receiving JSON over HTTP? In some cases, you could even make something that your users would install locally, and use without needing an Internet connection.
In my circles this is usually (perhaps incorrectly) called REST API.
Re: Everything I know about good API design
#60I'm not sure how would storing a key in Redis achieve idempotency in all failure cases. What's the algorithm? Imagine a server handling the request is doing a conditional write (like SET key 1 NX), and sees that the key is already stored. What then, skip creating a comment? Can't assume that the comment had been created before, since the process could have been killed in-between storing the key in Redis and actually creating the comment in the database.
An attempt to store idempotency key needs to be atomically committed (and rolled back in case it's unsuccessful) together with the operation payload, i.e. it always has to be a resource-specific id. For all intents and purposes, the idempotency key is the ID of the operation (request) being executed, be it "comment creation" or "comment update".