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

it2025-04-08  11

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

截图:

转载于:https://www.cnblogs.com/sink_cup/archive/2011/11/05/rest_uri_rewrite_header_version_number.html

相关资源:数据结构—成绩单生成器
最新回复(0)