Anyone 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.
drdaeman · 50m ago
I believe it’s pretty common to e.g. call libraries’ and frameworks’ user- (developer-) facing interface an API, like in “Python’s logging library has a weird-looking API”, so I don’t think API had eroded to mean only networked ones.
mettamage · 5m ago
I never understood why libraries also had the word API. From my understanding a library is a set of functions specific to a certain domain, such as a statistics library, for example. Then why would you need the word API? You already know it’s a library.
For end points it’s a bit different. You don’t know what are they or user facing or programmer facing.
I wonder if someone has a good take on this. I’m curious to learn.
shortrounddev2 · 52s ago
To me the API is the function prototypes. The DLL is the library
chubot · 49m ago
Well it stands for “application programming interface”, so I think it is valid to apply it to in-process interfaces as well as between-process interfaces
Some applications live in a single process, while others span processes and machines. There are clear differences, but also enough in common to speak of “APIs” for both
rogerthis · 32m ago
Things would come in SDKs, and docs were in MS Help .chm files.
j45 · 22m ago
APIs are for providing accessibility - to provide access to interactions and data inside an application from the outside.
The format and protocol of communication was never fixed.
In addition to the rest api’s of today, soap, wsdl, web sockets could all can deliver some form of API.
pixl97 · 2h ago
While 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.
andix · 26m ago
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.
claw-el · 1h ago
If there is a breaking change forced upon in the future, can’t we use a different name for the function?
Bjartr · 43m ago
See the many "Ex" variations of many functions in the Win32 API for examples of exactly that!
soulofmischief · 1h ago
A versioned API allows for you to ensure a given version has one way to do things and not 5, 4 of which are no longer supported but can't be removed. You can drop old weight without messing up legacy systems.
CharlesW · 56m ago
You could, but it just radically increases complexity in comparison to "version" knob in a URI, media type, or header.
dwattttt · 1h ago
The reminder to "never break userspace" is good, but people never bring up the other half of that statement: "we can and will break kernel APIs without warning".
It illustrates that the reminder isn't "never change an API in a way that breaks someone", it's the more nuanced "declare what's stable, and never break those".
delta_p_delta_x · 20m ago
Even if the kernel doesn't break userspace, GNU libc does, all the time, so the net effect is that Linux userspace is broken regardless of the kernel maintainers' efforts. Put simply, programs and libraries compiled on/for newer libc are ABI-incompatible or straight-up do not run on older libc, so everything needs to be upgraded in lockstep.
It is a bit ironic and a little funny that Windows solved this problem a couple decades ago with redistributables.
chubot · 53m ago
Yeah, famously there is no stable public driver API for Linux, which I believe was the motivation for Google’s Fuschia OS
So Linux is opinionated in both directions - towards user space and toward hardware - but in the opposite way
frabonacci · 1h ago
The reminder to "never break userspace" is gold and often overlooked.. ahem Spotify, Reddit and Twitter come to mind.
runroader · 1h ago
I think the only thing here that I don't agree with is that internal users are just users. Yes, they may be more technical - or likely other programmers, but they're busy too. Often they're building their own thing and don't have the time or ability to deal with your API churning.
If at all possible, take your time and dog-food your API before opening it up to others. Once it's opened, you're stuck and need to respect the "never break userspace" contract.
devmor · 1h ago
I think versioning still helps solve this problem.
There’s a lot of things you can do with internal users to prevent causing a burden though - often the most helpful one is just collaborating on the spec and making the working copy available to stakeholders. Even if it’s a living document, letting them have a frame of reference can be very helpful (as long as your office politics prevent them from causing issues for you over parts in progress they do not like.)
claw-el · 1h ago
> However, a technically-poor product can make it nearly impossible to build an elegant API. That’s because API design usually tracks the “basic resources” of a product (for instance, Jira’s resources would be issues, projects, users and so on). When those resources are set up awkwardly, that makes the API awkward as well.
One issue I have with weird resources are those that feel like unnecessary abstraction. It makes it hard for the human to read and understand intuitively, especially someone new to these set of APIs. Also, it makes it so much harder to troubleshoot during an incident.
xtacy · 2h ago
Are there good public examples of well designed APIs that have stood the test of time?
binaryturtle · 1h ago
I always thought the Amiga APIs with the tag lists were cool. You easily could extend the API/ABI w/o breaking anything at the binary level (assuming you made the calls accept tag lists as parameters to begin with, of course).
cyberax · 1h ago
I'm a bit of a different opinion on API versioning, but I can see the argument. I definitely disagree about idempotency: it's NOT optional. You don't have to require idempotency tokens for each request, but there should be an option to specify them. Stripe API clients are a good example here, they automatically generate idempotency tokens for you.
Things that's missing from this list but that were important for me at some points:
1. Deadlines. Your API should allow to specify the deadline after which the request is no longer going to matter. The API implementation can use this deadline to cancel any pending operations.
2. Closely related: backpressure and dependent services. Your API should be designed to not overload its own dependent services with useless retries. Some retries might be useful, but in general the API should quickly propagate the error status back to the callers.
3. Static stability. The system behind the API should be designed to fail static, so that it retains some functionality even if the mutating operations fail.
cyberax · 2h ago
> You should let people use your APIs with a long-lived API key.
Sigh... I wish this were not true. It's a shame that no alternatives have emerged so far.
TrueDuality · 1h ago
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.
maxwellg · 48m ago
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 instead.
rahkiin · 1h ago
If api keys do not need to ve stateless, every api key can become a refresh token with a full permission and validity lookup.
pixelatedindex · 1h ago
To add on, are they talking about access tokens or refresh tokens? It can’t be just one token, because then when it expires you have to update it manually from a portal or go through the same auth process, neither of which is good.
And what time frame is “long-lived”? IME access tokens almost always have a lifetime of one week and refresh tokens anywhere from 6 months to a year.
smj-edison · 47m ago
> Every integration with your API begins life as a simple script, and using an API key is the easiest way to get a simple script working. You want to make it as easy as possible for engineers to get started.
> ...You’re building it for a very wide cross-section of people, many of whom are not comfortable writing or reading code. If your API requires users to do anything difficult - like performing an OAuth handshake - many of those users will struggle.
Sounds like they're talking about onboarding specifically. I actually really like this idea, because I've certainly had my fair share of difficulty just trying to get the dang thing to work.
Security wise perhaps not the best, but mitigations like staging only or rate limiting seem sufficient to me.
rahkiin · 1h ago
Inthink they are talking about refresh token or Api Keys like PATs. Some value you pass in a header and it just works. No token flow.
And the key is valid for months and can be revoked
cyberax · 1h ago
If you're using APIs from third parties, the most typical authentication method is a static key that you stick in the "Authorization" HTTP header.
OAuth flows are not at all common for server-to-server communications.
In my perfect world, I would replace API keys with certificates and use mutual TLS for authentication.
nostrebored · 56m ago
In your perfect world, are you primarily the producer or consumer of the API?
I hate mTLS APIs because they often mean I need to change how my services are bundled and deployed. But to your point, if everything were mTLS I wouldn’t care.
For end points it’s a bit different. You don’t know what are they or user facing or programmer facing.
I wonder if someone has a good take on this. I’m curious to learn.
Some applications live in a single process, while others span processes and machines. There are clear differences, but also enough in common to speak of “APIs” for both
The format and protocol of communication was never fixed.
In addition to the rest api’s of today, soap, wsdl, web sockets could all can deliver some form of API.
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.
It illustrates that the reminder isn't "never change an API in a way that breaks someone", it's the more nuanced "declare what's stable, and never break those".
It is a bit ironic and a little funny that Windows solved this problem a couple decades ago with redistributables.
So Linux is opinionated in both directions - towards user space and toward hardware - but in the opposite way
If at all possible, take your time and dog-food your API before opening it up to others. Once it's opened, you're stuck and need to respect the "never break userspace" contract.
There’s a lot of things you can do with internal users to prevent causing a burden though - often the most helpful one is just collaborating on the spec and making the working copy available to stakeholders. Even if it’s a living document, letting them have a frame of reference can be very helpful (as long as your office politics prevent them from causing issues for you over parts in progress they do not like.)
One issue I have with weird resources are those that feel like unnecessary abstraction. It makes it hard for the human to read and understand intuitively, especially someone new to these set of APIs. Also, it makes it so much harder to troubleshoot during an incident.
Things that's missing from this list but that were important for me at some points:
1. Deadlines. Your API should allow to specify the deadline after which the request is no longer going to matter. The API implementation can use this deadline to cancel any pending operations.
2. Closely related: backpressure and dependent services. Your API should be designed to not overload its own dependent services with useless retries. Some retries might be useful, but in general the API should quickly propagate the error status back to the callers.
3. Static stability. The system behind the API should be designed to fail static, so that it retains some functionality even if the mutating operations fail.
Sigh... I wish this were not true. It's a shame that no alternatives have emerged so far.
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 instead.
And what time frame is “long-lived”? IME access tokens almost always have a lifetime of one week and refresh tokens anywhere from 6 months to a year.
> ...You’re building it for a very wide cross-section of people, many of whom are not comfortable writing or reading code. If your API requires users to do anything difficult - like performing an OAuth handshake - many of those users will struggle.
Sounds like they're talking about onboarding specifically. I actually really like this idea, because I've certainly had my fair share of difficulty just trying to get the dang thing to work.
Security wise perhaps not the best, but mitigations like staging only or rate limiting seem sufficient to me.
OAuth flows are not at all common for server-to-server communications.
In my perfect world, I would replace API keys with certificates and use mutual TLS for authentication.
I hate mTLS APIs because they often mean I need to change how my services are bundled and deployed. But to your point, if everything were mTLS I wouldn’t care.