I've implemented a PoC for versioned API https://github.com/apache/couchdb/pull/2832. The code is very ugly but it demonstrates how it could work.
Best regards, iilyak On 2020/04/27 14:55:10, Ilya Khlopotov <[email protected]> wrote: > Hello, > > The topic of API versioning was brought in the [Streaming API in CouchDB > 4.0](https://lists.apache.org/thread.html/ra8d16937cca332207d772844d2789f932fbc4572443a354391663b9c%40%3Cdev.couchdb.apache.org%3E) > thread. The tread proposes to add new API endpoints to introduce a response > structure change. The alternative approach could be to implement proper > support for different API versions. > > It would benefit CouchDB project if we would have support for API versioning. > Adding new endpoint is easy but it is very hard to deprecate or change the > old ones. With proper API versioning we can avoid the need to rewrite all > client applications at the same time. > > rnewson mentioned a good blog post about API versioning > (https://www.troyhunt.com/your-api-versioning-is-wrong-which-is/). The main > idea of the blog post is. There is no perfect solution it would be the best > to support all options so the user can choose which one to use. > > In that spirit I propose to implement four different ways of specifying the > API version (per endpoint): > > - Path based - `/_v{version_number}/{db}/_all_docs` > - Query parameter based - `/{db}/_all_docs?_v={version_number}` > - Accept / Content-Type headers in the form of `application/couchdb; > _v={version_number},application/json` > - Custom header - X-Couch-API: v2 > > The server would include response version in two places: > - Custom header - `X-Couch-API: v2` > - `Content-type: application/couchdb; _v={version_number},application/json` > > Implementation wise it would go as follows: > 1) we teach chttpd how to extract version (we set version to `1` if it is not > specified) > 2) we change arity of chttpd_handlers:url_handler/2 to pass API version > 3) we would update functions in chttpd_httpd_handlers.erl to match on API > version > ``` > url_handler(<<"_all_dbs">>, 1) -> fun > chttpd_misc:handle_all_dbs_req/1; > url_handler(<<"_all_dbs">>, 2) -> fun > chttpd_misc_v2:handle_all_dbs_req/1; > ... > db_handler(<<"_design">>, 1) -> fun chttpd_db:handle_design_req/2; > db_handler(<<"_design">>, 2) -> fun chttpd_db_v2:handle_design_req/2; > ... > design_handler(<<"_view">>, 1) -> fun chttpd_view:handle_view_req/3; > design_handler(<<"_view">>, 2) -> fun chttpd_view_v2:handle_view_req/3; > ``` > 4) Modify chttpd:send_response to set response version (pass additional > argument) > > I don't expect the implementation to exceed 20 lines of code (not counting > changes in arity of functions in chttpd_httpd_handlers). > > Best regards, > iilyak >
