Live data from Hacker News

How Shopify Manages API Versioning and Breaking Changes

engineering.shopify.com

21–30 of 95 posts

Re: How Shopify Manages API Versioning and Breaking Changes

#21
post #19

Earlier quoted context omitted.

What specifically about SaaS API constraints do you think makes a date-based approach more appealing than semver? My high-level feeling is that it’s just way more difficult to ship a SaaS API than a Ruby Gem, so adding semver to that is just another layer of API management everybody has to agree on. Do you agree with this assessment?

For most published libraries every old version is always available and upgrading is never mandatory. For SaaS APIs the constraints of the business means that very few businesses (Stripe being the notable exception) want to support more than a handful of versions at a time, which results in versions regularly reaching end-of-life and completely disappearing. In this world, upgrading to newer APIs is mandatory and fair…

Good points.

Do you think a combination of the two is possible, and how do you think that might work?

year.month.minor.patch?

Re: How Shopify Manages API Versioning and Breaking Changes

#22

Shopify made a change to their API that was easily measurable on who it would affect, but didn't email us. Refused to grant us a temporary exemption (they would do it for $2000/m they said). The end result? They've sunk my business. I've replaced shopify now by writing my own but it's too late. My customers have all gone to my competitors and we're looking at pivoting.

What was the change? AFAIK Shopify would never give a temporary exemption for money, that's very much against their philosophy as a SaaS. Either you provide accurate details or this is just FUD.

Re: How Shopify Manages API Versioning and Breaking Changes

#23

Hi everyone. As the founder of an API company, this article has me wondering about the semantics of versioning — so I thought I’d ask the community a question. I hope the Shopify API team doesn’t mind! When you all think about API versioning, what makes the most sense to you — a semver approach (major.minor.patch) a la NPM, or a date-based approach (2020-01-07) a la AWS? Or is some combination of the two desirable? A…

I don't think there's one right answer, but my opinion is:

- Treat APIs as immutable.

- Any mutation results in a wholly new API version, not a patch or minor update.

- The developer will learn what changed, and how much changed by reading the patchnotes, not looking at which semver numbers changed. This is probably a healthy practice to encourage.

- Don't change APIs so much. The interface should be very carefully designed and tested and shipped like an NES cartridge: consider it impossible to fix once its shipped.

Therefore just start with `1` and increment each time.

The reason I don't like semver is that it's a developer convenience that leads to sloppy practices. You built your product against a specific API. If the API changes, you need to re-run your entire API evaluation, testing, blessing workflow. If the delta is tiny (what would have been a patch change) then yay, your task is likely going to be very simple. But you shouldn't see a bump version update and decide you can cut corners.

Re: How Shopify Manages API Versioning and Breaking Changes

#25

Hi everyone. As the founder of an API company, this article has me wondering about the semantics of versioning — so I thought I’d ask the community a question. I hope the Shopify API team doesn’t mind! When you all think about API versioning, what makes the most sense to you — a semver approach (major.minor.patch) a la NPM, or a date-based approach (2020-01-07) a la AWS? Or is some combination of the two desirable? A…

I don't think there's one right answer, but my opinion is: - Treat APIs as immutable. - Any mutation results in a wholly new API version, not a patch or minor update. - The developer will learn what changed, and how much changed by reading the patchnotes, not looking at which semver numbers changed. This is probably a healthy practice to encourage. - Don't change APIs so much. The interface should be very carefully d…

I don’t disagree with your assessment on semver as it currently exists for, say, NPM packages.

I do think that with web APIs specifically, the surface area is a lot smaller — the HTTP interface is literally all you touch — so semver, in its purest form, is actually completely enforceable as long as you understand the API schema.

Our team has talked a lot about either hard-enforcing or automatically applying semver where applicable. My question to you is — does this sound reasonable, and if you knew a semver contract was actually bound to implementation (i.e. guaranteed and not implied), would you trust it more?

Re: How Shopify Manages API Versioning and Breaking Changes

#26
post #11
post #5

Earlier quoted context omitted.

Both don't say much without good changelog. But with semver you can say: ok, I want every new version up to a new minor version (all fixes). While with a date based version you don't know how 'breaking' the changes will be.

I never understood why we settled on semver. If I have a bug, it's a breaking change. If I fix this bug, it's also a breaking change.

Your presumption of a collective "we" is at the root of the problem: versioning is one of those things in development where the same word can mean very different things to different people (see also: agile, automated testing). Prior to semantic versioning, there was an approach that looked like an agreed-upon standard to consumers of software packages/ libraries/ APIs but was not.

On one extreme you had certain developers (who I am sympathetic to because it's my personality) who were loath to ever label something 1.0 because it implies Doneness and a freedom from bugs that can never be so. On the other side you had people at chop shops who would bump the major version of some boxed product every time they fixed two bugs. Even if you as a good developer did the research to discover that 0.7.6 of Package A was solid and 5 years older than Package B 7.6, there was a good chance someone above you would declare 7.6 > 0.7.6 and that it was paid-for software so "We can get support from them" and force you to work with a shittier product.

So "we" developers do what we almost always do: we cast about for a better solution and landed on one that made the meaning of version numbers opaque to anyone outside the guild of mages writing code.

In short, semantic versioning may suck hard, but it sucks less.

Re: How Shopify Manages API Versioning and Breaking Changes

#27
post #13

Hi everyone. As the founder of an API company, this article has me wondering about the semantics of versioning — so I thought I’d ask the community a question. I hope the Shopify API team doesn’t mind! When you all think about API versioning, what makes the most sense to you — a semver approach (major.minor.patch) a la NPM, or a date-based approach (2020-01-07) a la AWS? Or is some combination of the two desirable? A…

I prefer semver, but it's still not exactly what I want. What I'm looking for is the answer to 'how painful/risky is upgrading likely to be?'. I expect an x.x.1 release to be zero/low risk - small fixes only within current api and contract. I expect a 2.x.x release to come with major risk of breakage (and I'll almost always want to wait for 2.0.2-2.0.3 before actually upgrading - and I expect a 1.x.x -> 2.x.x release…

I’m pretty sure the semver definition for a x.2.x change is that you’re adding surface area to your interface, in a way that doesn’t overlap with existing surface area, i.e. bytes sent over the wire for x.1.x will result in the same response bytes for x.2.x, all else being equal.

Note that the phrase non-overlapping is where all the complexity is hidden; it’s actually tricky to guarantee that an addition hasn’t changed any existing queries. For example, adding an enum value will mess up clients who query with max(enum_value). Technically, they’re not sending the same bytes, so the change is non-overlapping, but the client might disagree :)

Re: How Shopify Manages API Versioning and Breaking Changes

#28
post #3

It's interesting to compare and contrast this method of API management with Stripe. As far as I understand, the Stripe api would continue to work indefinitely so long as you lock your api version, whereas Shopify would eventually break the app as they essentially backport breaking changes to older api versions. Initially, I thought Stripe's method was superior, and would provide the best API experience, but realized…

Funny that you mention Stripe, because it was definitely the canonical backwards compatibility API for me. ... Until just recently in mid Nov they changed some behavior that caused us to double/triple/quadruple charge customers unintentionally in some not-so-uncommon edge cases... I’m still trying to square this one with their support, so details are a bit thin. But definitely a big surprise for me to see this happen…

You know, you just jogged my memory here. We did have an issue with Stripe changing the order / timing of payment_failed webhooks, which caused them to be sent before the next payment attempt was known.

We used the payment failed hook to send an email to our customers and let them know when we'd be retrying the charge, which was no longer possible because the next_payment_attempt field was null. Before the change, a next_payment_attempt=null meant the charge would not be retried.

I reported the issue and the webhook changes were rolled back a month later. Really threw a wrench into our flow.

I will say that generally speaking, Stripe is the canonical backwards compatibility API in my mind. With a few edge cases.

Re: How Shopify Manages API Versioning and Breaking Changes

#29
post #3

It's interesting to compare and contrast this method of API management with Stripe. As far as I understand, the Stripe api would continue to work indefinitely so long as you lock your api version, whereas Shopify would eventually break the app as they essentially backport breaking changes to older api versions. Initially, I thought Stripe's method was superior, and would provide the best API experience, but realized…

>those apps continue to be updated and utilizing the latest features.

while this is orthogonal to Shopify API or your post at all, since you mentioned the need of updates, I just wanted to use that opportunity to vent my frustration with the constant push to update everything all the time and judging any piece of software by using "when was the last update" as a metric.

The problem I see is that not all apps or libs need (frequent) updates, many (maybe most) do need them, but some don't. They provide some functionality, they do that well and you could call them "complete". Maybe some security fix could be needed from time to time, but with a mature code being in use for many years event those are not frequent.

For example, consider something like ping utility. It does what it does for many decades. There was a need to add IPv6 support, but that was almost two decades ago. Why would anyone need to update it? I do not want any additional functionality, I don't want it to send emails or have social media share button. I want it to send ICMP echo requests and receive ICMP echo replies and nothing more. Aside from some security fixes no updates should be needed for 10+ years. This utility is done. It should not be thrown upon just because there were no updates for many years.

While of course neither ecommerce or Shopify platform are "done" and they get many updates now and will get updates in future it does not mean that some functionalities could have reached "done" stage.

For a "complete and done" addon, there could be a need for a security fix from time to time. There could be a need for some adjustments if a major browser introduces a new deviation from JS/CSS/HTML standards and forces everyone to update their code. But those events happen from time to time, possibly not that frequently. This means that some addon/plugin would not require any updates during the periods between those events and those periods could be many months/years long. But hey: "this addon did not receive any updates for 13 months, it must be really bad and should be avoided". This leads to a situation where a competing solution with tons of bugs will look better just because it receives two updates a week.

Re: How Shopify Manages API Versioning and Breaking Changes

#30

Hi everyone. As the founder of an API company, this article has me wondering about the semantics of versioning — so I thought I’d ask the community a question. I hope the Shopify API team doesn’t mind! When you all think about API versioning, what makes the most sense to you — a semver approach (major.minor.patch) a la NPM, or a date-based approach (2020-01-07) a la AWS? Or is some combination of the two desirable? A…

(Disclosure: I work at Google on public APIs, opinions are my own)

Google's proposed a "stability" semantic as a third option[0]. TL;DR no breaking changes in the Stable channel but you can add backwards-compatible[1] features in-place.

A permanent Beta channel that's a superset of Stable lets users choose how change-tolerant they are. This lets API producers launch features earlier, knowing they will only impact risk tolerant users if breaking changes are needed. Theoretically this reduces the need for breaking changes in Stable, which require a new Major version.

[0] https://aip.dev/181 [1] https://aip.dev/180

Post reply on HN