5 ms·
Version your API from day one (instead of company.com/api, support company.com/api/v1). This makes it a lot easier to support legacy users.
by gargarplex 7y ago
Version your API from day one (instead of company.com/api, support company.com/api/v1). This makes it a lot easier to support legacy users.
- mooreds 7y agoI actually have heard it is better to use headers for versioning. Here is a link with three options for versioning: https://restfulapi.net/versioning/ https://restfulapi.net/versioning/
- philwelch 7y agoThat's extremely fussy compared to versioning the endpoints. Harder to test, harder to implement, and delivers no real benefit.
- pojzon 7y agoHow exactly? How different it would be to pass a header instead of switching path ? Im was writing such tests in spock and pacts.io and it was extremely easy to do both.
- philwelch 7y agoFor the client, it's only marginally more difficult because you have to specify an extra header--since you'd have to specify the path anyway, versioning via path gives the client one less thing to specify. For the server, it's annoying because every backend framework I've encountered ultimately boils down to "here is a function that gets called when the server receives a request to a given path". If you're versioning by path, you just write a new function for the new path. If you version by header, now you have to have a single request-handling function that performs conditional logic based on a request header--at which point I would probably just dispatch to separate functions for each version, which is exactly what path-based versioning would give me for free. I'm also not exactly sure how, if at all, it's possible to document this type of behavior in OpenAPI/Swagger, if that's of any concern or relevance. All in all, versioning by header isn't dramatically more annoying than versioning by path, but I see virtually zero concrete benefit from incurring the cost in the first place.
- pojzon 7y agoI think there is more than enough resources on the web to understand stand points of each of those solutions. For me it seems like those are just tools created to tackle specific problems. Each has own pros and cons. Depending on usecase url based versioning may be worse than mime one. And vice versa. I just wanned to point out that api versioning can be done equally easly in both ways.
- philwelch 7y agoIt’s not “equally easy” though. I’m asking what the pros are, of versioning by header, and I’m not actually hearing a sensible response.
- mooreds 7y agoFrom the article I posted: "Using the URI is the most straightforward approach (and most commonly used as well) though it does violate the principle that a URI should refer to a unique resource. You are also guaranteed to break client integration when a version is updated." So versioning with content headers is useful when * it's really important that there is a one to one mapping between a URI and a resource (not /v1/customer/1 and /v2/customer/1 URIs which both refer to customer 1). I'm not familiar enough with API construction to know why this might be important, but maybe system clarity? * You have far flung clients that are not easy to update (iot, mobile apps, software that needs to be manually configured) and you want all clients to always go to the same URI (perhaps for whitelisting through a client firewall).
- philwelch 7y ago> it's really important that there is a one to one mapping between a URI and a resource (not /v1/customer/1 and /v2/customer/1 URIs which both refer to customer 1). I'm not familiar enough with API construction to know why this might be important, but maybe system clarity? This isn't important unless you take "True REST" seriously. This notion is a fussy little hobgoblin that most people rightly dispense with. > You have far flung clients that are not easy to update (iot, mobile apps, software that needs to be manually configured) and you want all clients to always go to the same URI (perhaps for whitelisting through a client firewall). Surely if I'm not updating some of the clients, they can just continue using the v1 endpoint while other clients use a v2 endpoint. I don't actually see how this helps.
- zeeZ 7y agoDon't put your API on the same Domain as your website. Use api.company.com or a dedicated domain instead of company.com/api.
- philwelch 7y agoInteresting. What's the rationale?
- gsempe 7y agoIt’s the separation of concerns best practice extended to domain names. To not have to think to path collisions if the website and the API are in the hands of different teams is a plus. As well, in this case, it’s a lot better to avoid the root domain which is less flexible then a subdomain. For instance, you can’t have a CNAME behind a root domain
- paulddraper 7y agoFlexibility. A CNAME is easier than a reverse proxy. Security. Don't share cookies with your site.
- philwelch 7y agoWhat if sharing cookies with your site is the intended behavior, e.g. for API's that you're calling directly from your frontend?
- hhas01 7y agoOr you could learn how to build REST-ful web interfaces correctly, in which case the problem goes away. The only #SeparationOfConcerns that actually matters is: 1. Verbs describe actions upon resources (e.g. add, read, delete) 2. URIs identify individual resources you may wish to act upon 3. Content Types (and content negotiation) determine how a particular resource’s information will be encoded for transfer between client and server. For instance, if a client has the following URI that points to a “person” resource: example.org/persons/12345 and the public documentation states that a person’s information can be represented in any of these formats: - "text/html" (a standard human-readable webpage) - "application/org.example.person+json" (JSON-encoded machine-readable data) - "application/org.example.person+xml" (XML-encoded machine-readable data) then the client can GET the resource’s data in one of three different formats, according to preference and/or need; e.g. standard web browser, custom smartphone app, Traditional Enterprise Application.
- hhas01 7y agoKnow how to design a RESTful interface correctly, and you don’t need “API versioning”. Certainly not URL-based versioning, which is as anti-REST as it gets. The correct way to manage non-backwards-compatible changes in a RESTful system is to define a new content type for the resource representation that has changed. For example, here is a JSON-encoded representation of a Person resource: {"name": "Bob Jones", "age": 42} To describe this particular data structure + encoding, we give it its own content type: "application/org.example.person+json" and provide public documentation for this representation type. To retrieve a description of a given person in this exact format, a client sends a GET request with an "Accept: application/org.example.person+json" header.† Let’s say after a while you decide to replace the "name" field with separate "firstName" and "lastName" fields: {"firstName": "Bob", "lastName": "Jones", "age": 42} This new representation clearly isn’t backwards-compatible, so give it a new content type that reflects this: "application/org.example.person.v2+json" and provide public documentation for this new representation type, alongside the documentation for the older format. A newly written/updated client that requires this improved information sends a GET request with an "Accept: application/org.example.person.v2+json" header. Existing clients that still use the old format continue to send GET requests with an "Accept: application/org.example.person+json" header. Where there are many such servers all around the world, it is likely that some will be older than others. A client that much prefers the new, more detailed, representation but is prepared to work with the old-style representation if that’s all it can get will send an Accept header containing both content types weighted by preference: "Accept: application/org.example.person.v2+json;q=1.0, application/org.example.person+json;q=0.3" No sequentially version-mangled URLs. No Grand New Major API Release Announcements. No “we have ended support for the v1 API so now you must switch to the v2”. Just flexible, reliable interactions between any number of clients and servers, where each client and each server is free to evolve naturally and non-disruptively over time. TL;DR: Everything you think you know about RESTful HTTP is completely and utterly WRONG. Same goes for everyone you learnt it from, and so on. #FractallyWrong -- † A client that doesn’t care what it receives as long as it’s JSON encoded can, of course, send an Accept header containing the basic "application/json" and if the server is happy to serve that particular idiot^Wtype then that’s what it gets back. A server is also free to represent the same resource in any number of encodings, e.g. "application/org.example.person+xml" (for All your Enterprisey™ clients), "text/html" (your Auntie Ena in her Internet Explorer 6 will always ask for this), and so on.