Live data from Hacker News

APIs as infrastructure: future-proofing Stripe with versioning

stripe.com

41–50 of 53 posts

Re: APIs as infrastructure: future-proofing Stripe with versioning

#41

Earlier quoted context omitted.

> Essentially, the old version becomes a consumer of the new version As a raw concept, I really like this idea. Let's say you're bumping from 2.5 to 2.6 and there's a breaking change in-between. You replace the old api code with a new thin layer that consumes 2.6 and puts it in 2.5 format. This would be easy to write a series of tests for to make sure that 2.5 is still providing what it should, and it has the added b…

Don't you mean the other way round? You always want to be running the most recent 2.6 servers, but when someone sends version 2.5 requests you transform the 2.5 to 2.6 and pass it along to your server (and vice Verda with responses) The problem I guess is breaking changes come easily - it's fine if say we have example.com/homeaddress and now I add a zip code field in 2.6 - but a 2.5 request has no zip code and if 2.6…

Maybe we're talking about the same thing, but basically, the way I see it is this:

1. Request for 2.5 comes in

2. Version 2.5 calls v2.6, takes the data, and transforms it into 2.5.

3. Since a 2.5 response shouldn't have a zipcode field, it's dropped from 2.6 before the 2.5 response is returned.

Re: APIs as infrastructure: future-proofing Stripe with versioning

#42
Versioning of APIs have existed since the dawn of time, or at least the early 90s. ONC RPCs had versioning built-in IIRC for all their XDR structs. We got away from that over the last few decades, and now people run into the same problems that were effectively solved almost 30 years ago, but long forgotten. The more things change, the more they stay the same!

Re: APIs as infrastructure: future-proofing Stripe with versioning

#44
post #37

I work on a SOA team at a large healthcare enterprise. We currently write mostly SOAP APIs (yeah, I know, 2017 and all that...), and follow a typical pattern as what Stripe describes: Whenever we do a version bump (which is extremely frequent, since a WSDL breaks a contract the moment you sneeze at it), we create an XSLT transform from the new version back to the old. So if you're calling version 2, but the current v…

If you can do an XSLT transformation to different versions I wonder how important the change was in the first place?

As TFA notes, replacing a boolean with an enumeration is a breaking change, but can be transformed back easily enough assuming the enumeration just increases the granularity of the original states.

And SOAP is usually schema-verified, so adding fields will generally be a breaking change.

Re: APIs as infrastructure: future-proofing Stripe with versioning

#45

Earlier quoted context omitted.

Don't you mean the other way round? You always want to be running the most recent 2.6 servers, but when someone sends version 2.5 requests you transform the 2.5 to 2.6 and pass it along to your server (and vice Verda with responses) The problem I guess is breaking changes come easily - it's fine if say we have example.com/homeaddress and now I add a zip code field in 2.6 - but a 2.5 request has no zip code and if 2.6…

Maybe we're talking about the same thing, but basically, the way I see it is this: 1. Request for 2.5 comes in 2. Version 2.5 calls v2.6, takes the data, and transforms it into 2.5. 3. Since a 2.5 response shouldn't have a zipcode field, it's dropped from 2.6 before the 2.5 response is returned.

This kind of implies always have 2.5 running as front end code. I would rather have my latest code running (especially as it implies 2.4,2.3,,,1.3) and have that spin up the 2.5 munger code as needed. But yes I think it's more or less the same thing

Interestingly looking at stripe changelog https://stripe.com/docs/upgrades#api-changelog they still do breaking code changes every month or two so despite the effort and with a smallish api they break a lot of contracts.

The odd thing is that they keep a different api version for each customer, tagged at customers settings, so I suspect your approach (spin up api based on incoming version) might work better - but boy I think they may be in a lot of pain trying to maintain that backwards compatibility

Re: APIs as infrastructure: future-proofing Stripe with versioning

#46
In our experience, API versioning hits a roadblock in three cases:

1. Mandatory new field.

2. Field is split. For example, address field is now divided into street1 and street2.

3. Change in datatype.

In the above three cases, we had to force users to upgrade their versions.

Re: APIs as infrastructure: future-proofing Stripe with versioning

#48

I work on a SOA team at a large healthcare enterprise. We currently write mostly SOAP APIs (yeah, I know, 2017 and all that...), and follow a typical pattern as what Stripe describes: Whenever we do a version bump (which is extremely frequent, since a WSDL breaks a contract the moment you sneeze at it), we create an XSLT transform from the new version back to the old. So if you're calling version 2, but the current v…

I worked for a place in the travel industry that was doing the same thing on our REST interface. That was a bit more relaxed since it's not the crazy WSDL so you could always add things to the interface without breaking, but it still allowed you to version cleanly. In something like 150 version releases (bi-weekly cadence, over the course of a few years), I believe there were 2 XSLTs in the version chain.

To the point of the XSLT being so trivial that maybe you didn't need the change, I recall one of our changes being around a field that got split into 2 fields. We certainly could have put special case code in to handle old version vs new version, but the great thing is, we didn't have to put that code in. It really keeps the interface a lot cleaner.

Also, XSLT is capable of some pretty advanced transformations, so I wouldn't dismiss it out of hand as triviality.

Regarding the documentation, we build all our docs off Javadoc and a few annotations, so docs were always current. As a bonus, when your Javadoc is used to generate public docs, you tend to treat it with more respect than Javadoc usually gets.

Re: APIs as infrastructure: future-proofing Stripe with versioning

#49
post #21
post #13

Github also versions their API via headers, but uses the `Accept` header instead: https://developer.github.com/v3/media/

I consider this a misuse of the Accept header. They're defining a bunch of custom media types, which in of itself is pretty weird, but then they're not actually using those media types as the Content-Type of the response. So I can send a request where I say 'Accept: application/vnd.github.full+json', but the response I get back is 'Content-Type: application/json; charset=utf-8', which means the server intentionally h…

>They're defining a bunch of custom media types, which in of itself is pretty weird,

No it isn't. If you're doing REST and your resources are not completely trivial (arguably, even if they are) you should be defining a custom media type for them (think HTML5).

>but then they're not actually using those media types as the Content-Type of the response.

Ok, that is very weird.

Re: APIs as infrastructure: future-proofing Stripe with versioning

#50

I work on a SOA team at a large healthcare enterprise. We currently write mostly SOAP APIs (yeah, I know, 2017 and all that...), and follow a typical pattern as what Stripe describes: Whenever we do a version bump (which is extremely frequent, since a WSDL breaks a contract the moment you sneeze at it), we create an XSLT transform from the new version back to the old. So if you're calling version 2, but the current v…

> there will be transforms back for 10->9, 9->8, 8->7... all the way back to 2. It works well enough.

We did something like this in the on a message bus: the channels had the version in the name and and older version service always asked for the same data on the next version channel (the only other version it knew about), and then transformed it before sending it on. This meant you never had to maintain anything accept your newest version. It also meant you could never completely remove data because versions going obsolete needed a way to find or derive it to create their older version.

Post reply on HN