【问题标题】:How to test RESTful api passing data in POST?如何在 POST 中测试 RESTful api 传递数据?
【发布时间】:2015-01-16 16:26:15
【问题描述】:

我需要从 cli 测试我的 php API。

这是我的 php 脚本 test.php:

<?php
    $request = new Request();
    if (isset($_SERVER['PATH_INFO'])) {
        $request->url_elements = explode('/', trim($_SERVER['PATH_INFO'], '/'));
    }
    $request->method = strtoupper($_SERVER['REQUEST_METHOD']);
    switch ($request->method) {
        case 'GET':
            $request->parameters = $_GET;
        break;
        case 'POST':
            $request->parameters = $_POST;
        break;
        case 'PUT':
            parse_str(file_get_contents('php://input'), $request->parameters);
        break;
    }
    print $request->method . ": "; print_r($request->parameters); # DEBUG
?>

这是我的尝试,使用 curl(如网络上广泛记录的......):

$ curl -X POST -H "Content-type: application/json" -d '{"key":"value"}' http://localhost/test.php

结果如下:

_GET: Array
(
)
_POST: Array
(
)

我希望 _POST 中的“键:值”...

我错过了什么?

P.S.:抱歉,我知道我犯了一些非常愚蠢的错误,我觉得自己很愚蠢...... :-(

【问题讨论】:

    标签: php api rest post curl


    【解决方案1】:

    您正在发布 JSON,但试图解释 urlform 编码的数据。你应该使用$postdata = file_get_contents("php://input");

    【讨论】:

    • 太棒了!谢谢...我知道我错过了一些简单的东西... :-)
    • 那么,我应该如何使用 curl 来发布 urlform 编码的数据呢?有可能吗(对不起,我是 HTTP 新手... :-()?
    【解决方案2】:

    您不应该以这种方式测试 REST API。测试代码不得包含任何 URI 结构。通过 REST 客户端,您必须始终遵循 API 提供的链接,并根据附加的元数据(例如链接关系、RDF 等)找到正确的链接。如果你不能遵循基本的REST constraints(在这种情况下统一接口约束),你为什么将你的 API 称为 REST?

    在您的情况下,GET http://example.com/api/v1/ 应该返回一个类似这样的链接:

    { relation: "http://example.com/api/v1/docs/createItem" uri: "http://example.com/api/v1/", method: "POST", headers: { contentType: "application/json" }, data: { key: "value" } }

    你的测试代码应该是这样的:

    $apiRoot = 'http://example.com/api/v1/'
    
    $response1 = getHttp($apiRoot);
    expect($response1->headers->statusCode)->toBe(200);
    $data1= parseJson($response1);
    
    $link2 = findLinkByRelation($data1, $apiRoot.'docs/myCollection/createItem');
    $response2 = followLink($link2);
    expect($response2->headers->statusCode)->toBe(201);
    $data2 = parseJson($response2);
    
    $link3 = findLinkByRelation($data2, $apiRoot.'docs/myCollection/getItem');
    $response3 = followLink($link3);
    expect($response3->headers->statusCode)->toBe(200);
    $data3 = parseJson($response3);
    expect($data3)->containProperty(array("key" => "value"));
    

    这样测试代码将像真实客户端一样松散耦合到服务实现,因此可以用作真实客户端的模板。

    顺便说一句。这称为服务的端到端测试。如果您在测试中通过覆盖超全局变量(如 $_SERVER、$_POST 等)来模拟 HTTP 部分,则可以使其更快。

    哦,我读到了你的问题。 $_POST 仅解析 application/x-www-form-urlencodedmultipart/form-data。因此,您必须使用输入流获取原始发布数据并手动解析它,但您真正需要的是 HTTP 框架,例如http://www.slimframework.com/http://symfony.com/ 等......它会自动执行此操作。但这不是关于你应该如何测试你的 API。 :-)

    【讨论】:

    • 你的回答不是很清楚,对我来说,对不起......你能详细说明一下吗?我确实更新了我的问题,展示了我的真实代码......你能举例说明如何从 cli 测试我的 API 吗?为什么我不应该将其命名为“REST”?
    • 我明白了...谢谢... 说实话,我使用“测试”一词的含义更为宽松(例如,在“端到端测试”或“单元测试”...)。对不起。我将在我的开发过程中进一步需要这些测试,现在我只是要求一种简单的方法在开发期间从命令行快速和肮脏地测试我的代码,以检查代码行为......我确实赞成你的答案,但它收到了反对票,不知道为什么......
    • @MarcoS 总有人不同意,这就是原因。 :-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-12
    • 2011-09-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-08-04
    • 1970-01-01
    相关资源
    最近更新 更多