| ▲ | pixl97 3 days 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. |
|
| ▲ | paulhodge 3 days ago | parent | next [-] |
| 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 endpoints with new names. (instead of naming anything "v2"). Then, if the entire API needs to be reworked, it's more likely that the team will just decide to deprecate the entire service/API, and then launch a new and better service with a different name to replace it. So in the end, it's really rare that any endpoints ever have "/v2" in the name. I've been in the industry 25 years and only once have I seen a service that had a "/v2" to go with its "/v1". |
| |
| ▲ | ks2048 3 days ago | parent | next [-] | | > So in the end, it's really rare that any endpoints ever have "/v2" in the name. 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). | |
| ▲ | grodriguez100 3 days ago | parent | prev [-] | | The author does not say that you “should not add v1”. They say that versioning is how you change your API responsibly (so, endorsing versioning), but that you should only do it as a last resort. So you would add “v1”, to be able to easily bump to v2 later if needed, and do your best to avoid bumping to v2 if at all possible. |
|
|
| ▲ | gitremote 3 days ago | parent | prev | next [-] |
| I don't think the author meant they don't include /v1 in the endpoint in the beginning. The point is that you should do everything to avoid having a /v2, because you would have to maintain two versions for every bug fix, which means making the same code change in two places or having extra conditional logic multiplied against any existing or new conditional logic. The code bases that support multiple versions look like spaghetti code, and it usually means that /v1 was not designed with future compatibility in mind. |
| |
| ▲ | account42 a day ago | parent [-] | | If you really care about maintaining v1 long-term you'd re-implement it as a small shim above v2. |
|
|
| ▲ | andix 3 days ago | parent | prev | next [-] |
| 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. |
| |
| ▲ | choult 3 days ago | parent [-] | | 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. | | |
| ▲ | pixl97 3 days ago | parent | next [-] | | This here, it's way easier to grep a file for /v1/ and show all the api endpoints then ensure you haven't missed something. | | |
| ▲ | andix 2 days ago | parent | next [-] | | Edit: ^/api(/(?!v[0-9]).)?$ is v1 ^/api/v2(/.)?$ is v2 It's really not an issue in any case, it just itches your brain, because is not as neat as you would like it to be. | |
| ▲ | cmcconomy 3 days ago | parent | prev [-] | | grep for /* and omit /v2 ? |
| |
| ▲ | andix 2 days ago | parent | prev [-] | | Switching to an incompatible/breaking API requires some rework anyway. The consumer of an API usually doesn't support multiple versions in parallel. |
|
|
|
| ▲ | JimDabell 3 days ago | parent | prev | next [-] |
| > 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 don’t really need to do that for REST APIs. If clients request application/vnd.foobar then you can always add application/vnd.foo.bar;version=2 later without planning this in advance. |
| |
| ▲ | 9dev 2 days ago | parent | next [-] | | Actually, there’s nothing stopping you from using a custom "Version: 2" Header in requests and responses | |
| ▲ | 946789987649 3 days ago | parent | prev | next [-] | | If you use something like an OpenAPI generator and want to have different DTOs in your version 2, then you cannot do what you suggested. | | |
| ▲ | jamietanna 2 days ago | parent | next [-] | | I've been using OpenAPI for years with multiple versioning types (header based, content negotiation + media type based) and haven't had issues across Java, Typescript or Go with generating the right code for it | |
| ▲ | JimDabell 3 days ago | parent | prev [-] | | You can specify multiple media types in OpenAPI. |
| |
| ▲ | lazyasciiart 3 days ago | parent | prev | next [-] | | Most REST APIs don’t support that. So you don’t need versioning for APIs that already have a request type specified. | | |
| ▲ | JimDabell 3 days ago | parent [-] | | I’m not sure what you mean in the context of a discussion about how to design APIs. If you are the one designing an API, it’s up to you what you support. | | |
| ▲ | lazyasciiart a day ago | parent [-] | | We call that baking them in from the very start of your application, which is what you claimed this didn’t need. |
|
| |
| ▲ | spixy 2 days ago | parent | prev [-] | | The problem is with parameters (or headers) you are still stuck with same API schema (you cannot rename it, etc). But thanks to versions, in my job we renamed old APIs like /v1/oauthApple and /v1/oauthGoogle to /v2/login/oauth/apple and /v2/login/oauth/google, looks so much better. | | |
| ▲ | JimDabell 2 days ago | parent [-] | | > The problem is with parameters (or headers) you are still stuck with same API schema (you cannot rename it, etc). That doesn’t make sense. The whole point of creating a new version is to change the schema. And what do you mean “rename it”? > But thanks to versions, in my job we renamed old APIs like /v1/oauthApple and /v1/oauthGoogle to /v2/login/oauth/apple and /v2/login/oauth/google, looks so much better. Wait, by schema do you mean URL structure? You’re looking at this backwards. The benefit of using headers is that you can keep the same URL. In a REST API, the URL is the primary key. If Client A holds a copy of /v1/foo/1 and Client B holds a copy of /v2/foo/1 then as far as HTTP and REST are concerned, those are two different resources and the clients cannot interoperate. If Client A holds a copy of /foo/1 in application/vnd.foo;version=1 format and Client B holds a copy of /foo/1 in application/vnd.foo;version=2 format, then those clients have the same resource and can interoperate. But if you want to change your URL structure, you can do that too. There’s nothing stopping you from moving /oauthApple to /oauth/apple, you don’t even need a new version to do that – just change the link. |
|
|
|
| ▲ | pbreit 3 days ago | parent | prev | next [-] |
| Disagree. Baking versioning in from the start means they will much more likely be used, which is a bad thing. |
|
| ▲ | grodriguez100 3 days ago | parent | prev | next [-] |
| I would say the author recommends the same actually: they say that versioning is “how you change your API responsibly” (so, endorsing versioning), but that you should only switch to a new version as a last resort. |
|
| ▲ | claw-el 3 days ago | parent | prev [-] |
| If there is a breaking change forced upon in the future, can’t we use a different name for the function? |
| |
| ▲ | soulofmischief 3 days ago | parent | next [-] | | 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. | |
| ▲ | Bjartr 3 days ago | parent | prev | next [-] | | See the many "Ex" variations of many functions in the Win32 API for examples of exactly that! | |
| ▲ | jahewson 3 days ago | parent | prev | next [-] | | /api/postsFinalFinalV2Copy1-2025(1)ExtraFixed | |
| ▲ | pixl97 3 days ago | parent | prev | next [-] | | Discoverability. /v1/downloadFile /v2/downloadFile Is much easier to check for a v3 then /api/downloadFile /api/downloadFileOver2gb /api/downloadSignedFile Etc. Etc. | | |
| ▲ | echelon 3 days ago | parent | next [-] | | I have only twice seen a service ever make a /v2. It's typically to declare bankruptcy on the entirety of /v1 and force eventual migration of everyone onto /v2 (if that's even possible). | | |
| ▲ | bigger_cheese 3 days ago | parent | next [-] | | A lot of the Unix/Linux Syscall api has a version 2+ For example dup(), dup2(), dup3() and pipe(), pipe2() etc LWN has an article:
https://lwn.net/Articles/585415/ It talks about avoiding this by designing future APIs using a flags bitmask to allow API to be extended in future. | |
| ▲ | pixl97 3 days ago | parent | prev [-] | | I work for a company that has an older api so it's defined in the header, but we're up to v6 at this point. Very useful for changes that have happened over the years. |
| |
| ▲ | claw-el 3 days ago | parent | prev [-] | | Isn’t having the name (e.g. Over2gb) easier to understand than just saying v2?
This is in the situation where there is breaking changes forced upon v1/downloadFile. |
| |
| ▲ | ks2048 3 days ago | parent | prev | next [-] | | If you only break one or two functions, it seems ok. But, some change in a core data type could break everything, so adding a prefix "/v2/" would probably be cleaner. | |
| ▲ | CharlesW 3 days ago | parent | prev | next [-] | | You could, but it just radically increases complexity in comparison to "version" knob in a URI, media type, or header. | |
| ▲ | 3 days ago | parent | prev [-] | | [deleted] |
|