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 
> 

Reply via email to