w3c-ccg / vc-issuer-http-api

A specification for an HTTP API used to issue Verifiable Credentials.
https://w3c-ccg.github.io/vc-http-api/
Other
7 stars 5 forks source link

Agree to API Versioning Scheme #24

Closed OR13 closed 4 years ago

OR13 commented 4 years ago

Seems there is objection to prefixing paths with version information:

/api/v0/issuer/credentials

However, it must be possible to version the API, and we need a way to bind the version of the API to a version of the spec....

Here are some example APIs that are versioned using headers:

I suggest we use semantic versioning:

We agree to publish GitHub releases matching the versioning scheme (v0.0.0), and we use the following Header Structure to request a specific version:

-H "VC-API-Version: 0.0.0"

OR13 commented 4 years ago

Additonal context for those who are not familiar with this topic: https://www.troyhunt.com/your-api-versioning-is-wrong-which-is/

TLDR; he recommends the GitHub Approach... I hesitate to recommend that approach today, because of uncertainties regarding JSON-LD and CBOR... we can migrate to it in the future, if we can agree to Semver.

msporny commented 4 years ago

Digital Bazaar would prefer to have versioning options provided in this order of preference:

Digital Bazaar would object strongly to:

If a version cannot be determined:

OR13 commented 4 years ago

Transmute would prefer not to pollute options or query string params with version information.

Can we agree to using HTTP Headers for v0.0.1, and table support for other variants until a subsequent version?

Github and Stripe had more time to think about this problem and they chose HTTP Headers... We can of course state in v2.0.0 that version must be supplied using another method, or multiple options (with priority).

See also:

@msporny please provide supporting references for using query string or post body options.

Of course post body options won't work for GET or DELETE.

OR13 commented 4 years ago

Some support for using query strings here:

OR13 commented 4 years ago

I can see allowing query strings to be very useful, but I'd prefer to tackle that later.

mkhraisha commented 4 years ago

What is the argument against URI versioning? it seems like the easiest and fastest to implement, and most of the arguments i see against it is "purity", am i missing anything or is that the only major argument?

For the record Header/query strings are both perfectly fine for us and would not pose any issues.

msporny commented 4 years ago

Alright, looks like Digital Bazaar's first option will get push back from Transmute, and the second option may be a more workable option.

Digital Bazaar is fine w/ versioning in Header Parameters for the next two months until we revisit this.

At this point, looks like Transmute, SecureKey, Mavennet, and Digital Bazaar agree. Anyone else have any objections? Does anyone think anyone else in the cohort will object? @peacekeeper -- would be great to get your feedback on this, I know it's getting late over where you are.

OR13 commented 4 years ago

One argument for URI Path Based Versioning is that different version of the API will map to different resources, and therefore a /v1/issuer/credentials would be different than a /v2/issuer/credentials...

An argument against the Accept header, is that you might want a v2 credential in xml/rdf... and a v1 credential in json, and v3 credential in CBOR.

All of these are fine assuming that you don't use the accept header:

POST /v1/issuer/credentials-> json POST /issuer/credentials/123?api-version=v2 -> json POST /issuer/credentials/123 (header : api-version=v2, accept xml/rdf ) -> xml

From a REST perspective, you are supposed to embrace HTTP... a major argument against doing this is that you want to treat HTTP like a dumb pipe and embed all this stuff in your payloads...

We could require 100% of the endpoints to be POST, and do this stuff in the post body options.

That would be more in line with DIDComm...

The more we use HTTP Headers or query params, or paths, the less Message oriented, the less DIDComm oriented.

IMO, if you are building a REST API, you should try to follow REST... You should use HTTP Verbs, HTTP Headers, HTTP Query Strings, and you should avoid pushing tons of stuff into a POST Body....

UNLESS

You specifically state that you are trying to be message oriented and not restful, in which case your API should look like:

POST /messages { message }

I'm not opposed to the latter, its just wildly different than v0.0.1

If we want to make this more of a message oriented / rpc api... we should discuss that in isolation from versioning.. I'm assuming we are trying to version a restful HTTP API... path and query string are friendlier for HTTP GET... Transmute generally prefers path based versioning because of the restful resource alignment.

Our preferences are:

msporny commented 4 years ago

What is the argument against URI versioning?

This is one of the many things that have been written on the topic:

http://blog.steveklabnik.com/posts/2011-07-03-nobody-understands-rest-or-http

Read everything from the top down to "I want my API to be versioned". It's a decent introduction to the space.... There are other things to consider, but that might get you started.

We need to take the blog post above, and the ones that @OR13 pointed to into account when designing this HTTP API... remember, we're building something that's going to eventually be the way things are done on the Web... so we need to make sure we're not sloppy... which means everyone should be aware of RESTful design and HTTP API design. There are a large series of trade-offs that will need to be made... and being too academic/purist about can also be bad... there is rarely a purely right/wrong answer. It's all a balancing act.

OR13 commented 4 years ago

Worth noting that swagger autogen will handle support for URI based versioning automatically... whereas query string or header based support will be trickier to get working since you can't simply introspect the registered routes.... of course, you can always build your swagger by hand.

David-Chadwick commented 4 years ago

"Additonal context for those who are not familiar with this topic: https://www.troyhunt.com/your-api-versioning-is-wrong-which-is/"

Conceptually I disagree with Troy. Version 2 of anything is not the same as Version 1. If it were, why would anyone buy a new version of anything if it was identical to the original version? My latest Macbook Pro is a different resource to my previous one. So I would argue that the resource has changed. Its been updated, which is why we have issued version 2 of the API, and therefore to use the path of the URL seems perfectly correct to me. New resource, new URL.

peacekeeper commented 4 years ago

I'm not very experienced in API versioning and therefore don't really have a preference. URL path based versioning seems easiest to me, but several downsides were mentioned in this thread.

I will gladly follow my colleagues' lead on this issue...

OR13 commented 4 years ago

We agreed to headers for now, we will likely want to add support for query string if there are get requests in the future.

OR13 commented 4 years ago

Closing for now.