`
erichi101
  • 浏览: 11327 次
文章分类
社区版块
存档分类
最新评论

RESTful API版本控制策略

阅读更多

做RESTful开放平台,一方面其API变动越少, 对API调用者越有利;另一方面,没有人可以预测未来,系统在发展的过程中,不可避免的需要添加新的资源,或者修改现有资源。因此,改动升级必不可少,但是,作为平台开发者,你必须有觉悟:一旦你的API开放出去,有人开始用了,你就不能只管自己Happy了,你对平台的任何改动都需要考虑对当前用户的影响。因此,做开放平台,你从第一个API的设计就需要开始API的版本控制策略问题,API的版本控制策略就像是开放平台和平台用户之间的长期协议,其设计的好坏将直接决定用户是否使用该平台,或者说用户在使用之后是否会因为某次版本升级直接弃用该平台。 

版本控制策略模式 
API的版本控制策略通常有3种模式: 
第一种:The Knot:无版本,即平台的API永远只有一个版本,所有的用户都必须使用最新的API,任何API的修改都会影响到平台所有的用户。甚至平台的整个生态系统。 
 
第二种:Point-to-Point:点对点,即平台的API版本自带版本号,用户根据自己的需求选择使用对应的API,需要使用新的API特性,用户必须自己升级。 
 
第三种:Compatible Versioning:兼容性版本控制,和The Knot一样,平台只有一个版本,但是最新版本需要兼容以前版本的API行为。 
 
三种策略对整个平台在升级API的开销对比如下: 

以上信息来源于这篇文章:http://www.ebpml.org/blog2/index.php/2013/11/25/understanding-the-costs-of-versioning 
作者以数学的方式详细的论述了这三种模式下,整个平台在升级API上的开销对比。 

针对上面的论述,首先,API一定得有版本,否则升级对于用户来说将是噩梦。其次,要做到Compatible Versioning有现实的限制,毕竟API升级时,不可避免的会出现无法兼容老版本的状况,因此,版本控制需要结合第二种和第三种模式,即提供一个统一的兼容版本入口,同时对于不能兼容历史版本的API保留历史版本,支持用户能够调用到历史版本的API。另外,对历史版本的API支持一定要有时间和用户限制,即老版API支持到一定时间就删除,新用户必须使用新版API,否则一个API有10个版本会让平台的维护非常痛苦。 

URI vs Request Parameter vs Media Type 
在RESTful API领域,关于如何做版本控制,目前业界比较主流的有3种做法: 
第一种:URI, 即在URI中直接标记使用的是哪个版本,无版本号URI默认使用最新版本。如下: 

Java代码  收藏代码
  1. http://xianlinbox/api/customers/1234  
  2. http://xianlinbox/api/v3.0/customers/1234  

好处: 
直接可以在URI中直观的看到API版本, 
可以直接在浏览器的查看各个版本API的结果 
坏处: 
版本号在URI中破坏了REST的HATEOAS(hypermedia as the engine of application state)规则。版本号和资源之间并无直接关系。 

第二种:Request Parameter, 即在每个请求后添加一个version参数,表示请求的是哪个版本。如下: 

Java代码  收藏代码
  1. http://server:port/api/customer/123?version=2  


这种做法其实就是URI方式的变种,好坏处也都一样。 

第三种: Media Type, 即在HTTP请求的header中使用Media Type标记该请求想获取的资源, 同样的可以不设置或设置通用的Media Type表示最新版本的API。 

Java代码  收藏代码
  1. ===>  
  2. GET /customer/123 HTTP/1.1  
  3. Accept: application/vnd.xianlinbox.customer-v3+json  
  4.   
  5. <===  
  6. HTTP/1.1 200 OK  
  7. Content-Type: application/vnd.xianlinbox.customer-v3+json  
  8.   
  9. {"customer":  
  10.   {"name":"Xianlinbox"}  
  11. }  

好处: 
遵循了REST的设计风格, 
坏处: 
版本不直观,需要能设置header的client才能调用查看该API的效果。

 

zz:https://www.cnblogs.com/kenshinobiy/p/4462424.html

------------------------------------------------------------------------------------------------

 

REST URI设计:版本号放在http header中,rewrite配置

 

REST API新版本上线后,旧版本要继续在线,所以要做多版本并行。

服务器代码目录

api.example.com/

                          0.1/

                               controller

                               model

                               htdocs/index.php

                          0.2/

                               controller

                               model

                               htdocs/index.php

 

之前做的URI是这样的:

curl http://api.example.com/0.2/users/1

web server需要做rewrite,把各个版本的请求路由到 {v}/www/index.php。

版本号的格式为:11.11.11,即([0-9]+\.)+[0-9]+

这时候apache这么配:

    DocumentRoot "/api.example.com/"
    ServerName api.example.com
    RewriteEngine On
    RewriteRule ^/(([0-9]+\.)+[0-9]+)/ /$1/www/index.php

更多的了解REST以后,觉得把版本号、access_token放在header中更符合资源的概念。

参考:http://www.ruanyifeng.com/blog/2011/09/restful.html

URI改成这样:

curl -H 'Accept:application/json; version=0.2' http://api.example.com/users/1

这个时候需要web server从header中解析到版本号,然后路由。

这个时候apache这么配:

    DocumentRoot "/api.example.com/"
    ServerName api.example.com
    RewriteEngine On
    RewriteCond  %{HTTP_ACCEPT}  version=(([0-9]+\.)+[0-9]+) 
    RewriteRule ^(.+)$ - [env=v:%1]
    RewriteCond  %{HTTP_ACCEPT}  version=(([0-9]+\.)+[0-9]+)
    RewriteRule  .*   /%{ENV:v}/htdocs/index.php
    #RewriteLogLevel 9
    #RewriteLog logs/api.example.com-rewrite_log

在网上查了半天,才试出来apache rewrite从header中取变量。

nginx 这么配:

复制代码
server {
    listen       8080;
    server_name  api.example.com;
    root html/api;
    #access_log   logs/api.example.com/access.log combined buffer=32k;
    access_log   logs/api.example.com/trunk/access.log combined;
    error_log    logs/api.example.com/trunk/error.log;

    location = /robots.txt {
        expires 1d;
    }
    location = /favicon.ico {
        expires 1d;
    }

    location / {
        rewrite ^/$ /docs.php last;
        set $api_version "enabled";
        if ($uri ~ "((([0-9]+\.)+[0-9]+)|trunk)/docs/.*") {
            set $api_version $1;
            rewrite ^/((([0-9]+\.)+[0-9]+)|trunk)/docs/$ /$api_version/htdocs/docs/index.html break;
            rewrite ^/((([0-9]+\.)+[0-9]+)|trunk)/docs/(.*)$ /$api_version/htdocs/docs/$4 break;
        }
        if ($http_accept ~ "application/json; version=((([0-9]+\.)+[0-9]+)|trunk)") {
            set $api_version $1;
        }
        rewrite .* /$api_version/htdocs/index.php last;
    }

    location ~ \.php$ {
        fastcgi_pass   unix:/home/lnmp/php/var/run/php-fpm.sock;
        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
        include        fastcgi_params;
    }

    error_page  404              /404.html;
    location = /404.html {
        root   html;
    }

    error_page  500 502 503 504  /50x.html;
    location = /50x.html {
        root   html;
    }
}
复制代码

注意:nginx if中的rewrite不能直接使用$1,而要先set。

参考资料:

how to use a variable inside a nginx “if” regular expression

http://stackoverflow.com/questions/5859848/how-to-use-a-variable-inside-a-nginx-if-regular-expression

apache [env=ps:http] %{ENV:ps}

http://www.askapache.com/htaccess/http-https-rewriterule-redirect.html

apache rewrite 变量 %{}

http://httpd.apache.org/docs/current/mod/mod_rewrite.html#RewriteCond

apache rewrite %N $N

http://httpd.apache.org/docs/current/mod/mod_rewrite.html#RewriteRule

apache [E=VAR:VAL] [env

http://httpd.apache.org/docs/2.2/rewrite/flags.html#flag_e

截图:

 

 

分享到:
评论

相关推荐

    RESTful API设计:API版本控制策略.docx

    RESTful API设计:API版本控制策略.docx

    RESTFUL API设置最佳实

    适当的版本控制策略可以帮助开发者平滑过渡到新的 API 版本,同时保持旧版本的兼容性。 常见的版本控制策略包括: 1. **URL 版本**:通过 URL 来区分不同的 API 版本,如 `/v1/tickets`。 2. **请求头版本**:通过...

    webapi 源码 Restful 版本控制

    版本控制在 RESTful API 设计中是至关重要的,因为它允许服务在不中断现有客户端的情况下进行更新和改进。 在WebAPI中实现RESTful版本控制,主要考虑以下几点: 1. **URL 包含版本信息**:最直观的方式是在URL路径...

    Laravel开发-restfulapi

    "Laravel开发-restfulapi"的主题着重于使用Laravel框架创建RESTful API。REST(Representational State Transfer)是一种网络应用程序的设计风格和开发方式,基于HTTP协议,以资源为中心,通过统一的接口进行交互。 ...

    lighttpd restfulapi cgi

    1. **权限控制**:确保API接口有适当的访问限制,如认证和授权机制。 2. **错误处理**:提供清晰的错误响应,便于客户端调试。 3. **缓存策略**:根据资源特性设置合适的缓存策略,提高性能。 4. **日志记录**:记录...

    restful 接口开发规范(RESTfulAPIdesignguide)

    6. 版本控制:在URI中加入版本号,以使API能够向前兼容,如/v1、/v2等。 遵循以上规范,我们可以设计出清晰、一致且易于理解的RESTful API。这些规范不仅有助于接口的维护,也方便了第三方的集成,因为它们提供了一...

    Go-从任何PostgreSQL数据库提供RESTfulAPI

    11. **文档和API版本控制**:提供清晰的API文档,可能使用Swagger或ReDoc等工具,以及版本控制策略,以便在未来进行不破坏现有接口的更新。 在"prest-prest-51b5ee8"这个文件中,可能包含了名为"Prest"的开源项目,...

    用于基于Rails的RESTful API进行版本控制的插件。-Ruby开发

    Versionist开箱即用地支持三种版本控制策略:通过HTTP标头指定版本通过在路径之前添加版本标记来指定版本versionist一个用于对基于Rails的RESTful API进行版本控制的插件。 Versionist支持三种开箱即用的版本控制...

    RestfulAPI开发示例

    6. 版本控制:为了保持向后兼容,API开发者会为不同的版本创建不同的URL,如/v1/users和/v2/users。 7. 安全性:RESTful API通常使用OAuth、JWT(Json Web Tokens)进行身份验证和授权。这些机制可以保护API免受...

    基于thinkphp5的restful接口框架TPR

    - 接口版本控制:为保持接口的兼容性,TPR可能包含版本号,如/v1/users。 - 路由规则:利用ThinkPHP5的路由功能,定义RESTful接口的URL规则。 - 控制器设计:每个资源通常对应一个控制器,包含CRUD操作方法。 - ...

    JS application backed by a JavaEE RESTful API

    9. **性能优化**:缓存策略、负载均衡、API版本控制等都是提升系统性能和扩展性的关键。比如,使用HTTP缓存头可以减少不必要的网络请求,API版本管理可以确保旧版本应用的兼容性。 10. **持续集成/持续部署(CI/CD)*...

    TWAIN Direct Specification- RESTful API

    总的来说,TWAIN Direct RESTful API提供了一套标准化的、基于HTTP的扫描仪控制接口,旨在简化开发过程,提高跨平台兼容性,并通过引入现代网络技术和安全机制,保证数据传输的安全和可靠性。随着规范的不断完善,...

    Hands-On RESTful API Design Patterns and Best Practices

    - **版本控制**:通过URL或自定义头部等方式明确API版本,避免新旧客户端之间的兼容性问题。 - **负载均衡**:合理分配流量至多个服务器节点,提高系统的整体吞吐量。 #### 5. 安全性保障 安全性是RESTful API设计...

    iMaster NCE-Campus V300R019C10SPC207 RESTful API开发指南

    4. **资源模型**:阐述iMaster NCE-Campus中的网络资源模型,如设备、VLAN、IP地址、用户接入控制策略等,并说明如何通过API进行增删改查操作。 5. **示例代码**:提供不同编程语言(如Python、JavaScript等)的...

    iMaster NCE-Fabric V100R021C10 RESTful API开发指南(chm)

    iMaster NCE-Fabric是华为推出的一款数据中心自动驾驶网络管理控制系统,其V100R021C10版本提供了RESTful API的开发指南。RESTful API是Representational State Transfer(表述性状态转移)架构风格的接口,广泛应用...

    RESTful API 设计最佳实践1

    总的来说,RESTful API设计最佳实践强调了资源导向、HTTP方法的正确使用、简洁的URL结构、版本控制和安全性,旨在创建出高效、易用且可维护的Web服务接口。通过遵循这些原则,开发者可以构建出符合现代Web标准,满足...

    iMaster NCE-WAN V100R020C10 RESTful API参考

    9. **版本管理**:理解版本控制策略,如何兼容旧版本API,以及何时迁移至新版本。 10. **API文档**:CHM(Compiled HTML Help)文件是一种常见的帮助文档格式,提供了离线阅读和搜索功能,方便开发者快速查找所需...

    Gateway 是一个基于HTTP协议的restful的API网关

    5. **限流与熔断**:为了保护系统免受过载或恶意攻击,Gateway可以实施流量控制策略,限制并发请求的数量。此外,它还可以实现熔断机制,当后端服务出现问题时,自动断开连接,避免雪崩效应。 6. **监控与日志**:...

    iMaster NCE-WAN V100R020C00 RESTful API参考

    6. **安全控制**:实施访问控制策略,防止未授权访问,保护网络资源安全。 7. **网络拓扑发现**:自动发现并构建SD-WAN网络的拓扑结构,方便管理和维护。 8. **日志和报警**:收集和分析系统日志,触发报警机制,...

    Test Driven Development of a Django RESTful API

    - 支持多种认证协议,包括权限控制和速率限制策略。 - 可以对单个用户发出的API请求进行速率限制。 #### 序列化器(Serializers) - 序列化器是一种优雅的方式来验证模型查询集/实例,并将它们转换为原生Python数据...

Global site tag (gtag.js) - Google Analytics