From dev-return-49277-archive-asf-public=cust-asf.ponee.io@couchdb.apache.org Mon Apr 27 19:41:05 2020 Return-Path: X-Original-To: archive-asf-public@cust-asf.ponee.io Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [207.244.88.153]) by mx-eu-01.ponee.io (Postfix) with SMTP id A9D75180637 for ; Mon, 27 Apr 2020 21:41:04 +0200 (CEST) Received: (qmail 27815 invoked by uid 500); 27 Apr 2020 19:41:04 -0000 Mailing-List: contact dev-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list dev@couchdb.apache.org Received: (qmail 27800 invoked by uid 99); 27 Apr 2020 19:41:03 -0000 Received: from ui-eu-02.ponee.io (HELO localhost) (116.202.110.96) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 27 Apr 2020 19:41:03 +0000 Subject: Re: API versioning In-Reply-To: Message-ID: x-ponymail-agent: PonyMail Composer/0.2 References: To: Date: Mon, 27 Apr 2020 19:41:02 -0000 x-ponymail-sender: 3fd039c72976f9f89629fb5b95d0a929c183add0 Content-Type: text/plain; charset=utf-8 From: Ilya Khlopotov MIME-Version: 1.0 X-Mailer: LuaSocket 3.0-rc1 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 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 >