It uses Accept and Content-Type to version resources: application/vnd.company.article-v1+json
I only half agree with the sentiment that /api/v1 violates REST patterns. I don't think there's any guarantee that /api/v1/bars/123 can't be the same object as /api/v2/bars/123.
For other fields like your example of `avatar_url` I would use a placeholder avatar for all legacy users (the grey anonymous snowman profile comes to mind).
For example, in financial services and insurance, regs change and what data we need to collect change and sometimes their dependency will change. I am curious what's companies that have grown substantially had to do to their APIs.
Coming at this from a strongly-typed background, you acknowledge the fact that despite new regulations requiring a scan of the user's birth certificate in order to get an API token, that field can't be marked as non-null if you don't in fact have all those birth certificates. You are then forced to handle both the null and not-null cases when retrieving the value from the database.
So your API v2 can absolutely (in its MVC or whatever model) have that field marked as non-null but since your API v1 will still be proxying code to the same database, your db model would have that field marked as nullable (until the day when you have collected that field for all your customers).
If a downstream operation is contingent on the field being non-null, you are forced to grapple with the reality that you don't have said field for all your users (because of APIv1 users) and so you need to throw some sort of 400 Bad Request or similar error because (due to regulations) this operation is no longer allowed past some sunset date for users that haven't complied with regulation XYZ. In this case, it's a benefit that your db model has the field marked as null because it forces you to handle the cases where you don't have that field.
I guess what I'm saying is the db model isn't what you wish your data were like but rather what your data actually is, whether you like it or not.
We're working in this space at the moment, (eliminating the pain from breaking changes in APIs) and looking to get feedback on what we're building.
We're all from banking backgrounds, so understand the reg headaches you're talking about.
Can we chat?
Then if we absolutely do need a field non-null in the db, we run a backfill with either derived or dummy data. Then we can make the column non-null.
We use alembic to manage migration versions.
But we aren't even out of v0 endpoint and our stack is small enough that we have a lot of wiggle room. No idea how scalable this approach is.
The downside is maintaining separate api and db models, but the upside is decoupling things that really aren't the same. We tried an ORM which has a single model for both (Ormar) and it just wasn't mature, but also explicit conversions from wire format to db format are nice.
https://test.salesforce.com/services/Soap/c/47.0
And in the latest version of the API docs they have details regarding old versions. Example:
https://developer.salesforce.com/docs/atlas.en-us.api.meta/a...
Type reference Properties Create, Filter, Group, Nillable, Sort Description The ID of the parent object record that relates to this action plan.
For API version 48 and later, supported parent objects are Account, AssetsAndLiabilities, BusinessMilestone, Campaign, Card, Case, Claim, Contact, Contract, Financial Account, Financial Goal, Financial Holding, InsurancePolicy, InsurancePolicyCoverage, Lead, Opportunity, PersonLifeEvent, ResidentialLoanApplication, and Visit as well as custom objects with activities enabled.
For API version 47 and later, supported parent objects are Account, BusinessMilestone, Campaign, Case, Claim, Contact, Contract, InsurancePolicy, InsurancePolicyCoverage, Lead, Opportunity, PersonLifeEvent, and Visit as well as custom objects with activities enabled.
For API version 46 and later, supported parent objects are Account, Campaign, Case, Contact, Contract, Lead, and Opportunity as well as custom objects with activities enabled.
For API version 45 and earlier: the only supported parent object is Account.
Obviously there will be always challenges with eventually consistency but that is another topic altogether.
Since this field is validated in the DB, merely having `v1` `v2` distinction at the API layer is not sufficient. So I was thinking we will have to either 1) disable DB validations and rely on app validations or 2) run two separate systems (e.g., one DB per version) and let people 'upgrade' to the new version (once you upgrade you cannot go back).
Even though people refer to Stripe's API versioning blog, I don't recall any mention of actual data model changes and how it is actually managed