New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How To API Evolution Article #30

Merged
merged 7 commits into from May 4, 2018

Conversation

@philsturgeon
Copy link
Owner

philsturgeon commented May 3, 2018

Possibly needs more use cases, or better ones, or examples of things you cant do.

Have a read!

@philsturgeon philsturgeon force-pushed the evolution branch 2 times, most recently from bd6abef to 662b43e May 3, 2018

First pass at an API evolution article
Possiby needs more use cases, or better ones, or examples of shit you cant do.

@philsturgeon philsturgeon force-pushed the evolution branch from 662b43e to 151d316 May 3, 2018


JSON Schema is considering [adding a deprecated keyword](https://github.com/json-schema-org/json-schema-spec/issues/74), and oops I think I'm in charge of making that happen. I'll get back to doing that after this blog post. The idea here would be to pair the schema with a smart SDK (client code) which detects which fields are being used. If the schema marks the `foo` field as deprecated, and the client code then calls `$response->foo`, in PHP that could be snooped on with `function __get` (dynamic programming yaaaay) and fire off deprecation warnings on use.

GraphQL has the advantage when it comes to field deprecation for sure, as their type system demands clients to specify the fields they want. This is the sort of advantage you get when your type system, clients, etc. are all part of the same package, but HTTP in general can achieve this same functionality through standards.

This comment has been minimized.

@MikeRalphson

MikeRalphson May 3, 2018

This comes across as a bit of a non-sequiteur - at least to me. How does having the client specify required fields actually help if you want to make one of those fields go away, or be deprecated?

This comment has been minimized.

@philsturgeon

philsturgeon May 3, 2018

Owner

Gotcha! Will expand. Basically if you know who's asking for it, you can contact that client (manually or automatically) and suggest they change it. Or shove warnings into the payload somehow.


> We have too many old fields kicking around, we need to get rid of them.
Deprecations can be communicated in a few ways for API's. For those using OpenAPI v3, you can mark it as `deprecated: true` in the documentation. That's no ideal, of course, as OpenAPI is usually human-readable documentation, sat out of band on a developer portal somewhere. Rarely are OpenAPI schemas shoved into the response like JSON Schema is, so programatically clients have no real way to access this.

This comment has been minimized.

@adamaltman

adamaltman May 3, 2018

typo: should be... programmatically (I think)

This comment has been minimized.

@philsturgeon

philsturgeon May 3, 2018

Owner

Thanks, fixed!

@cebe
Copy link

cebe left a comment

good writeup, clear and understandable :)

At a lot of startups, this sort of conceptual change is common. No number of new fields is going to help out here, as the whole "one record = one match = one driver + one passenger" concept was junk. We'd need to make it so folks could accept a carpool based on the group, and any one of those folks could drive on a given day.

Luckily, business names often change fairly regularly in the sort of companies that have fundamental changes lie this. There is often a better word that folks have been itching to switch to, and evolution gives you a chance to leverage that change to your benefit.

This comment has been minimized.

@cebe

cebe May 3, 2018

lie -> like

Deprecating the whole concept of "matches", a new concept of "riders" can be created. This resource would track folks far beyond just being "matched", through the whole lifecycle of the carpool, thanks to a status field containing pending, active, inactive, blocked, etc.

By creating this a new `/riders` endpoint, this new resource can have a brand new representation. As always, the same database fields can be used internally, the same internal alerting tools are used for letting folks know about matches (v1 app) or new pending riders (v2 app). The API can create and update "matches" through this new "riders" interface. Clients can then use either one, and the code just figures itself out in the background. Over time the refactoring can be done to move the internal logic more towards riders, and your [integration tests / contract tests](https://blog.apisyouwonthate.com/tricking-colleagues-into-writing-documentation-via-contract-testing-206308b47e05) will confirm that things aren't changing on the outside.

This comment has been minimized.

@cebe

cebe May 3, 2018

how would the matches endpoint return data where there is more than one driver? If the data does not fit the endpoint anymore, it must be broken or fail for such data. Mentioning this would show the limits of evolution.

This comment has been minimized.

@nhocki

nhocki May 3, 2018

@philsturgeon If I remember correctly, we only exposed the first driver to the older apps. If the user accepted it, great... The other ones would be denied...

If the user rejected the first one, we would show the next one, and the next one, and the next one...

This comment has been minimized.

@philsturgeon

philsturgeon May 4, 2018

Owner

Aha! That was it. Awesome work :)

@cjunge-work

This comment has been minimized.

not matter how annoying that might be should be no matter how annoying that might be

@fmvilas
Copy link

fmvilas left a comment

Great article Phil! What about adding examples of situations when you can't avoid breaking the API. I'm asking for it because, to be fair, I can't think of any example right now. Thanks for taking the time put all these things together.

Ok! [Currencies are hard](https://gist.github.com/rgs/6509585), so this sort of thing is not uncommon. Let's start [using micros](https://support.siftscience.com/hc/en-us/articles/203869406-The-amount-field) instead.

We don't want to just outright change this value from dollars to cents because then we'd start charging $1,000,000 for stuff that should only cost $1, and folks probably wouldn't like that. Let's make a new field: `price_micros`.

This comment has been minimized.

@fmvilas

fmvilas May 3, 2018

I may be too strict here, but 1 dollar is not 1,000,000 cents. If you're just exaggerating, then forget my comment.

This comment has been minimized.

@cjunge-work

cjunge-work May 3, 2018

Phil's using micros :)

This comment has been minimized.

@philsturgeon

philsturgeon May 4, 2018

Owner

Great spot! I changed from subunits to micros mid article and some of this crap was left over. I cleaned it up here. ffa7c69


Deprecating the whole concept of "matches", a new concept of "riders" can be created. This resource would track folks far beyond just being "matched", through the whole lifecycle of the carpool, thanks to a status field containing pending, active, inactive, blocked, etc.

By creating this a new `/riders` endpoint, this new resource can have a brand new representation. As always, the same database fields can be used internally, the same internal alerting tools are used for letting folks know about matches (v1 app) or new pending riders (v2 app). The API can create and update "matches" through this new "riders" interface. Clients can then use either one, and the code just figures itself out in the background. Over time the refactoring can be done to move the internal logic more towards riders, and your [integration tests / contract tests](https://blog.apisyouwonthate.com/tricking-colleagues-into-writing-documentation-via-contract-testing-206308b47e05) will confirm that things aren't changing on the outside.

This comment has been minimized.

@fmvilas

fmvilas May 3, 2018

3 times new in the first sentence. You might want to rephrase it.

This comment has been minimized.

@philsturgeon

philsturgeon May 4, 2018

Owner

Gross! Overedited sentance makes no sense. Fixed.

Evolution involves thinking a little differently to how you approach change. Often there are simple things you can do to keep clients ticking along, and whilst clients will have to change at _some point_, the whole goal here is to allow them a decent amount of time to make that switch, with the minimal change possible during that change, and **no lock-step deploys** required.

And yes, whilst making a new endpoint to switch `/matches` and `/riders` is essentially the same as `/v1/matches` and `/v2/matches`, you've skipped the [quagmire of tradeoffs](https://blog.apisyouwonthate.com/api-versioning-has-no-right-way-f3c75457c0b7) between global versioning, resource versioning, or **gulp** method versioning. Global versioning has it's place, but so does evolution.

This comment has been minimized.

@fmvilas

fmvilas May 3, 2018

Should it be "has its place"?

This comment has been minimized.

@philsturgeon

philsturgeon May 4, 2018

Owner

English is my first language. 😅

@kevinswiber
Copy link

kevinswiber left a comment

I marked a few grammar issues. It looks pretty good to me.

I'd consider adding a punch list near the top with the gist of each problem->solution pair. Lots of times, people come to an article like this with the mindset of, "Just tell me what to do!" Just a suggestion. You have your own voice and style. :)

Content-wise, I think this is fairly comprehensive. I dig it.


## What is API Evolution

API Evolution is the concept of striving to maintain the "I" in API, the request/response body, query parameters, general functionality, etc., only breaking them when you absolutely, _absolutely_, have to. It's the idea that API developers bending over backwards to maintain a contract, not matter how annoying that might be, is often more financially and logistically viable than dumping onto a wide array of clients.

This comment has been minimized.

@kevinswiber

kevinswiber May 3, 2018

not matter how -> no matter how


## Examples

> The field `name` exists, and that needs to be splint into `first_name` and `last_name`.

This comment has been minimized.

@kevinswiber

kevinswiber May 3, 2018

splint -> split


> Deprecating a specific type of authentication from an endpoint, it's time to say goodbye to HTTP Basic Auth.
If they the client is making a request with an authorization header, they have some sort of account. If during the signup for that account you've asked them for an email, you can contact them. If you've not got any way to contact them... tough. Monitor how many folks are using HTTP basic, blog about it, shove some videos up, and eventually you're just going to have to turn it off.

This comment has been minimized.

@kevinswiber

kevinswiber May 3, 2018

If they the -> If the


## What is API Evolution

API Evolution is the concept of striving to maintain the "I" in API, the request/response body, query parameters, general functionality, etc., only breaking them when you absolutely, _absolutely_, have to. It's the idea that API developers bending over backwards to maintain a contract, not matter how annoying that might be, is often more financially and logistically viable than dumping onto a wide array of clients.

This comment has been minimized.

@josephgardner

josephgardner May 3, 2018

is often more financially and logistically viable than dumping onto a wide array of clients.

suggest instead saying "is often more financially, logistically, and perceptively viable than potentially disrupting/disabling a wide array of clients."

This comment has been minimized.

@tpluscode

tpluscode May 4, 2018

Or at least if it was like "dumping responsibility"?

This comment has been minimized.

@philsturgeon

philsturgeon May 4, 2018

Owner

Got it! Thank you:

It's the idea that API developers bending over backwards to maintain a contract, no matter how annoying that might be, is often more financially and logistically viable than dumping the workload a wide array of clients.


> The field `price` needs to stop being dollars/pounds/whatever as we're starting to support currencies that don't fit into "unit" and "subunit".
Ok! [Currencies are hard](https://gist.github.com/rgs/6509585), so this sort of thing is not uncommon. Let's start [using micros](https://support.siftscience.com/hc/en-us/articles/203869406-The-amount-field) instead.

This comment has been minimized.

@josephgardner

josephgardner May 3, 2018

OK "micros" sent me down a bit of a wild goose chase; is there anything more authoritative about this currency unit? I see adwords and twitter use it (sometimes), but they all provide their own definition and formula. This has me wondering if you are seriously suggesting API developers use this or only for illustration, but I'm not able to find more substance.

This comment has been minimized.

@philsturgeon

philsturgeon May 4, 2018

Owner

I expanded on the topic a bit. It's used in a fair few places, but basicalluy im kinda teach folks some things in the process. Otherwise people say "ugh thats wrong why would you recommend that" and I dont need that noise right now.


We don't want to just outright change this value from dollars to cents because then we'd start charging $1,000,000 for stuff that should only cost $1, and folks probably wouldn't like that. Let's make a new field: `price_micros`.

Now clients can either send the `price` field, and it'll convert. This will only work for the older currencies, and if `currency` is a field in the resource (or something nearby) then it's easy enough to support `price` for whatever initial currencies you had (dollar/pound/euro) and throw an error if somebody tries using price for these newer currencies, pointing them instead to the micro field.

This comment has been minimized.

@josephgardner

josephgardner May 3, 2018

your use of either in "clients can either send the price field" without an "or" in the sentence seems inconclusive.


> We have too many old fields kicking around, we need to get rid of them.
Deprecations can be communicated in a few ways for API's. For those using OpenAPI v3, you can mark it as `deprecated: true` in the documentation. That's no ideal, of course, as OpenAPI is usually human-readable documentation, sat out of band on a developer portal somewhere. Rarely are OpenAPI schemas shoved into the response like JSON Schema is, so programmatically clients have no real way to access this.

This comment has been minimized.

@josephgardner

josephgardner May 3, 2018

typo, "that's not ideal" ?


Deprecating the whole concept of "matches", a new concept of "riders" can be created. This resource would track folks far beyond just being "matched", through the whole lifecycle of the carpool, thanks to a status field containing pending, active, inactive, blocked, etc.

By creating this a new `/riders` endpoint, this new resource can have a brand new representation. As always, the same database fields can be used internally, the same internal alerting tools are used for letting folks know about matches (v1 app) or new pending riders (v2 app). The API can create and update "matches" through this new "riders" interface. Clients can then use either one, and the code just figures itself out in the background. Over time the refactoring can be done to move the internal logic more towards riders, and your [integration tests / contract tests](https://blog.apisyouwonthate.com/tricking-colleagues-into-writing-documentation-via-contract-testing-206308b47e05) will confirm that things aren't changing on the outside.

This comment has been minimized.

@josephgardner

josephgardner May 3, 2018

typo, "creating this a new"


All of that said, removing old fields is usually not all that much of a rush or an issue. Over time new developers will be writing new integrations, looking at your new documentation that tells them to use the new field, and your developer newsletters or changelogs just let them know to move away from it over time.

> A carpooling company that has "matches" as a relationship between "drivers" and "passengers", suggesting folks who could ride together, containing properties like "passenger_id" and "driver_id". Now we need multiple drivers, so this whole matches concept is garbage.

This comment has been minimized.

@josephgardner

josephgardner May 3, 2018

Now we need multiple drivers

This example is a bit hard to follow. Do you mean "now we need to support a person being both a driver OR a passenger?"

This comment has been minimized.

@philsturgeon

philsturgeon May 4, 2018

Owner

Now we need to support carpools that can have multiple drivers (i.e: Frank and Sally both take it in turns to drive), so this whole matches concept is garbage.


> Changing validation rules, something seemingly backwards compatible, like making the length of a field a little longer.
Changing validation rules seems like it might be a backwards compatible change, but often it is not. For example, making a string field accept a longer value can lead to some interesting problems. As clients often bake validation rules into client applications based on whatever the documentation says, if that documentation changes they aren't going to notice, and that validation will mismatch on different clients.

This comment has been minimized.

@josephgardner

josephgardner May 3, 2018

This isn't very convincing as backwards incompatible; this particular example won't "break" any clients, just they won't benefit from the additional available length. Maybe in addition, provide an example of wanting to introduce more restrictive validation which is definitely breaking.

This comment has been minimized.

@tpluscode

tpluscode May 4, 2018

So, maybe this example could be change to a scenario where the maximum length is decreased?

This comment has been minimized.

@darrelmiller

darrelmiller May 4, 2018

@josephgardner It can break clients. Client libraries are often built to allow you to GET an object, make some modifications and then PUT it back. If you are using a down-rev client and retrieve an object that has a description that is longer than the old constraint, the GET/change/PUT flow will fail.

This comment has been minimized.

@darrelmiller

darrelmiller May 4, 2018

There is an even more insidious issue with optional fields which we all assume are non-breaking. However, what happens when an up-rev client sets an optional value and then a down-rev client that knows nothing about the optional value, does a GET/change/PUT flow. The update will not contain the optional value and the PUT semantics cause the optional value to be deleted. So far the only solution I have found for this is to version the message.

This comment has been minimized.

@darrelmiller

darrelmiller May 4, 2018

… or do user-agent sniffing (ick)

This comment has been minimized.

@philsturgeon

philsturgeon May 4, 2018

Owner

Updated this in 06712a4, thank you !


And yes, whilst making a new endpoint to switch `/matches` and `/riders` is essentially the same as `/v1/matches` and `/v2/matches`, you've skipped the [quagmire of tradeoffs](https://blog.apisyouwonthate.com/api-versioning-has-no-right-way-f3c75457c0b7) between global versioning, resource versioning, or **gulp** method versioning. Global versioning has it's place, but so does evolution.

Think about it this way. If implementing some change takes twice as long for API developers compared to other versioning approaches, but save 6 or 7 client developer teams from having to do a while bunch of work, testing, etc. to chase new versions, this has been worthwhile to the company in terms of engineering hours spent.

This comment has been minimized.

@josephgardner

josephgardner May 3, 2018

typo "while bunch of work"


And yes, whilst making a new endpoint to switch `/matches` and `/riders` is essentially the same as `/v1/matches` and `/v2/matches`, you've skipped the [quagmire of tradeoffs](https://blog.apisyouwonthate.com/api-versioning-has-no-right-way-f3c75457c0b7) between global versioning, resource versioning, or **gulp** method versioning. Global versioning has it's place, but so does evolution.

Think about it this way. If implementing some change takes twice as long for API developers compared to other versioning approaches, but save 6 or 7 client developer teams from having to do a while bunch of work, testing, etc. to chase new versions, this has been worthwhile to the company in terms of engineering hours spent.

This comment has been minimized.

@josephgardner

josephgardner May 3, 2018

worthwhile to the company in terms of engineering hours spent.

Also worth mentioning is the ROI for keeping customers/clients happy


## What is API Evolution

API Evolution is the concept of striving to maintain the "I" in API, the request/response body, query parameters, general functionality, etc., only breaking them when you absolutely, _absolutely_, have to. It's the idea that API developers bending over backwards to maintain a contract, not matter how annoying that might be, is often more financially and logistically viable than dumping onto a wide array of clients.

This comment has been minimized.

@tpluscode

tpluscode May 4, 2018

Or at least if it was like "dumping responsibility"?


API Evolution is the concept of striving to maintain the "I" in API, the request/response body, query parameters, general functionality, etc., only breaking them when you absolutely, _absolutely_, have to. It's the idea that API developers bending over backwards to maintain a contract, not matter how annoying that might be, is often more financially and logistically viable than dumping onto a wide array of clients.

At some point change cannot be prevented, so at that time evolution suggests you provide sensible warnings to clients, letting them know if a feature they're using is going away, and not bothering them otherwise.

This comment has been minimized.

@tpluscode

tpluscode May 4, 2018

I think it should say "breaking change"


> Changing validation rules, something seemingly backwards compatible, like making the length of a field a little longer.
Changing validation rules seems like it might be a backwards compatible change, but often it is not. For example, making a string field accept a longer value can lead to some interesting problems. As clients often bake validation rules into client applications based on whatever the documentation says, if that documentation changes they aren't going to notice, and that validation will mismatch on different clients.

This comment has been minimized.

@tpluscode

tpluscode May 4, 2018

So, maybe this example could be change to a scenario where the maximum length is decreased?

Evolution involves thinking a little differently to how you approach change. Often there are simple things you can do to keep clients ticking along, and whilst clients will have to change at _some point_, the whole goal here is to allow them a decent amount of time to make that switch, with the minimal change possible during that change, and **no lock-step deploys** required.

And yes, whilst making a new endpoint to switch `/matches` and `/riders` is essentially the same as `/v1/matches` and `/v2/matches`, you've skipped the [quagmire of tradeoffs](https://blog.apisyouwonthate.com/api-versioning-has-no-right-way-f3c75457c0b7) between global versioning, resource versioning, or **gulp** method versioning. Global versioning has it's place, but so does evolution.

This comment has been minimized.

@tpluscode

tpluscode May 4, 2018

Well, /matches => /riders is not the same as /v1/matches => /v2/matches. The latter affects the entire API space. I see where you're coming from. Maybe this statement can be softened a little.

-is essentially the same as
+is not much better than

@philsturgeon philsturgeon force-pushed the evolution branch 2 times, most recently from 92f5d75 to 18f7956 May 4, 2018

@philsturgeon philsturgeon force-pushed the evolution branch from 0ecde17 to 6e4dd12 May 4, 2018

@philsturgeon

This comment has been minimized.

Copy link
Owner

philsturgeon commented May 4, 2018

Thanks @kevinswiber!

I would love it if this thing starts off a bunch of people trying to #WellActually NAHH UHHHH me where they give specific examples and I reply with specific examples. I could make a whole repo of them, it'd be dope! :D

For now im gonna keep it this style, and if it that happens I'll updated this with a link to the repo/gitsts. :)

@philsturgeon philsturgeon changed the title First pass at an API evolution article How To API Evolution Article May 4, 2018

@darrelmiller

This comment has been minimized.

Copy link

darrelmiller commented May 4, 2018

LGTM

Prempt the folks laughing about emails/blog
Obviously folks are gonna say 'OMG he's literally saying emails and blogs are how you should handle change' and I'll say 'Yup like Google 🤷‍♂️''

@philsturgeon philsturgeon merged commit 11d9988 into middleman May 4, 2018

@philsturgeon philsturgeon deleted the evolution branch May 4, 2018

philsturgeon added a commit that referenced this pull request May 4, 2018


## What is API Evolution

API Evolution is the concept of striving to maintain the "I" in API, the request/response body, query parameters, general functionality, etc., only breaking them when you absolutely, _absolutely_, have to. It's the idea that API developers bending over backwards to maintain a contract, no matter how annoying that might be, is often more financially and logistically viable than dumping the workload a wide array of clients.

This comment has been minimized.

@tpluscode

tpluscode May 4, 2018

Should it be "dumping the workload on"?

tags:
---

There are a lot of pro's and con's to various approaches to API versioning, but that has been covered in depth before: _[API Versioning Has No "Right" Way](https://blog.apisyouwonthate.com/api-versioning-has-no-right-way-f3c75457c0b7)_.

This comment has been minimized.

@dplassgit

dplassgit May 4, 2018

*pros and cons (no apostrophes)

@@ -0,0 +1,146 @@
---
title: API Evolution for REST/HTTP APIs

This comment has been minimized.

@dplassgit

dplassgit May 4, 2018

Throughout this doc: is it API Evolution (capital E) or API evolution (lower case e?). I don't care either way as long as it's consistent.

This comment has been minimized.

@philsturgeon
end
```

When folks `POST` or `PATCH` to your API, if they send a `name` you can convert it, if they send `first_name` and `last_name` it'll get picked up fine on the serializer. Job done.

This comment has been minimized.

@dplassgit

dplassgit May 4, 2018

*or if they send


Want to keep it simple and go with cents, pence, etc.? Fine, `price_subunits` will do. If somebody grumps about that and you want a more concise name, just call it `amount` and point folks towards that field instead. A thesaurus is handy.

Why don't we just outright change this value from dollars to micros? because then we'd start charging $1,000,000 for stuff that should only cost $1, and folks probably wouldn't like that.

This comment has been minimized.

@dplassgit
Switching to an integer to place your cents, pence, etc. would be just as much of a [Fallacies Programmers Think About Currencies](https://gist.github.com/rgs/6509585) as using float dollars/pounds, etc. To support the widest array of currencies, some folks like to use "micros", a concept explained well here by [Sift Science](https://support.siftscience.com/hc/en-us/articles/203869406-The-amount-field). In this case, the new field could easily be called `price_micros`.

Want to keep it simple and go with cents, pence, etc.? Fine, `price_subunits` will do. If somebody grumps about that and you want a more concise name, just call it `amount` and point folks towards that field instead. A thesaurus is handy.

This comment has been minimized.

@dplassgit

dplassgit May 4, 2018

I don't understand this. If you're supporting currencies that don't support "unit" and "subunit", then why would use use "price_subunits"?

This comment has been minimized.

@philsturgeon

philsturgeon May 4, 2018

Owner

Ha, this chopped and changed so much... I forgot to check the question when rewriting the section :D

Deprecations can be communicated in a few ways for API's. For those using OpenAPI v3, you can mark it as `deprecated: true` in the documentation. That's no ideal, of course, as OpenAPI is usually human-readable documentation, sat out of band on a developer portal somewhere. Rarely are OpenAPI schemas shoved into the response like JSON Schema is, so programmatically clients have no real way to access this.

JSON Schema is considering [adding a deprecated keyword](https://github.com/json-schema-org/json-schema-spec/issues/74), and oops I think I'm in charge of making that happen. I'll get back to doing that after this blog post. The idea here would be to pair the schema with a smart SDK (client code) which detects which fields are being used. If the schema marks the `foo` field as deprecated, and the client code then calls `$response->foo`, in PHP that could be snooped on with `function __get` (dynamic programming yaaaay) and fire off deprecation warnings on use.

This comment has been minimized.

@dplassgit

dplassgit May 4, 2018

Who, there's a lot here. I'd nuke the PHP references (nothing against PHP, sorry not sorry) as it doesn't seem to add much to the discussion. CMIIW, but the point of this paragraph is that if you distribute a client library, you can programatically (at runtime or compile time) make things deprecated.

This comment has been minimized.

@philsturgeon

philsturgeon May 4, 2018

Owner

The idea here would be to pair the schema with a smart SDK (client code) which detects which fields are being used. If the schema marks the foo field as deprecated, and the client code then calls $response->foo, the SDK can raise a deprecation warning. This is achieved by inspecting the schema file at runtime if you offer your schemas in the Link header, or at compile time if you're distributing schema files with the SDK.

Much better thank you!


All of that said, removing old fields is usually not all that much of a rush or an issue. Over time new developers will be writing new integrations, looking at your new documentation that tells them to use the new field, and your developer newsletters or changelogs just let them know to move away from it over time.

> A carpooling company that has "matches" as a relationship between "drivers" and "passengers", suggesting folks who could ride together, containing properties like "passenger_id" and "driver_id". Now we need to support carpools that can have multiple drivers (i.e: Frank and Sally both take it in turns to drive), so this whole matches concept is garbage.

This comment has been minimized.

@dplassgit

dplassgit May 4, 2018

"i.e.," not "i.e:"


## Summary

Evolution involves thinking a little differently to how you approach change. Often there are simple things you can do to keep clients ticking along, and whilst clients will have to change at _some point_, the whole goal here is to allow them a decent amount of time to make that switch, with the minimal change possible during that change, and **no lock-step deploys** required.

This comment has been minimized.

@dplassgit

dplassgit May 4, 2018

"*on how" not "to how"


And yes, whilst making a new endpoint to switch `/matches` and `/riders` is essentially the same as `/v1/matches` and `/v2/matches`, you've skipped the [quagmire of tradeoffs](https://blog.apisyouwonthate.com/api-versioning-has-no-right-way-f3c75457c0b7) between global versioning, resource versioning, or **gulp** method versioning. Global versioning has its place, but so does evolution.

Think about it this way. If implementing some change takes twice as long for API developers compared to other versioning approaches, but save 6 or 7 client developer teams from having to do a while bunch of work, testing, etc. to chase new versions, this has been worthwhile to the company in terms of engineering hours spent.

This comment has been minimized.

@dplassgit

dplassgit May 4, 2018

*whole bunch of work, not "while bunch of work"

Shoving a clear error into your HTTP response (here using the amazing [RFC 7807: Problems for HTTP APIs](https://tools.ietf.org/html/rfc7807)):

```
HTTP/1.1 403 Forbidden

This comment has been minimized.

@dplassgit

dplassgit May 4, 2018

Does this solution apply to other problems as well?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment