在RESTful API中使用Clean url


Using Clean URLs in RESTful API

"Clean url "也称为"RESTful url "是用户友好的,纯结构化的,不包含查询字符串。相反,它们只包含资源的路径。

即:"http://twitter.com/users/show/"+用户名+ " . json "

服务器端功能问题:

  1. 我需要为每个目录做一个唯一的服务器端API脚本吗?

  2. 我可以把所有的请求转发到一个脚本,如果是这样的话,我怎么做从干净的URL结构($_GET['url_structure'])拉有用的信息?

  3. 为什么twitter调用。json文件这肯定是不存在的。它必须根据请求生成。如何这能起作用吗?这让我相信问题的答案

1)如果您使用rest式框架,如RecessPHP或如果您在.htaccess文件中使用mod_rewrite规则将所有API请求重定向到单个PHP文件(称为前端控制器),则不会。

. htaccess

RewriteEngine On
RewriteRule ^/api/ api.php

api.php

$request = $_SERVER['REQUEST_URI'];  //this would be /users/show/abc.json

2)您可以使用apache的重写模块将所有api请求重定向到处理它们的特殊PHP文件。根据您的apache配置,原始请求的(RESTful) url将存储在PHP的服务器变量中,我相信它是$_SERVER['REQUEST_URI']。当然,您也可以将包含RESTful url的$_GET[]变量传递给PHP。

. htaccess

RewriteEngine On
RewriteRule ^/api/([^'.]+).(xml|json|atom) api.php?url=$1&type=$2

api.php

$request_parts = explode('/', $_GET['url']); // array('users', 'show', 'abc')
$file_type     = $_GET['type'];
$output = get_data_from_db(); //Do your processing here
                              //You can outsource to other files via an include/require
//Output based on request
switch($file_type) {
    case 'json':
        echo json_encode($output);
        break;
    case 'xml':
        echo xml_encode($output); //This isn't a real function, but you can make one
        break;
    default:
        echo $output;
}

3) Twitter(和许多其他API)使用这种方法,因为它是提供应用程序期望从API返回的格式的方便方法。所有API请求都被重新路由到一个PHP文件,该文件处理创建所有文件并将其内容回显到输出。该文件从未实际存储在服务器上(除非它被缓存)。


好资源

  • mod_rewrite,初学者指南
  • 使用PHP创建REST API

关于RecessPHP的说明。它当然是一个伟大的工具,我鼓励你看看它(也许在它的源代码得到一个想法,它是如何处理的东西),但也就是说,它似乎对我有点笨拙。在我看来,用特殊注释写路径名很不php。我会偏离这一点,我不会说它是完美的框架,但它确实是一个开始。好运!

这对我来说很有效:把这个放到你网站根目录下的htaccess文件中。

<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule api/(.*)$ api/api.php?request=$1 [QSA,NC,L]
RewriteRule (recipe/.*) api/app.php?request=$1 [QSA,NC,L]
</IfModule>

然后如果你去http://localhost/api/person/susan页面您将看到它将您带到位于http://localhost/api/api.php的文件我也有一个食谱页面,我使用http://localhost/recipe/edit/2把它放到api.php文件中:

<?php
$requestParts = explode('/',$_GET['request']);
$category = $requestParts[0];
$action = $requestParts[1];
$data = $requestParts[2];
if($category == 'recipe'){
    include($_SERVER['DOCUMENT_ROOT'].'/pages/add_recipe.php');
}

上面的变量将保存类别:recipe, action: add或edit,数据可以是一个数字,这个数字是recipe的id或任何你想要的数据。然后在add_recipe.php中使用这些变量来确定您是在编辑还是在添加菜谱。如果你使用api,你可以包含不同的文件,这取决于你使用什么ajax请求来与你的api。

试试这个:

RewriteRule ^([^/]+)'/([^/]+)'/?$ getdata.php?para1=$1&para2=$2 [NC]