与不同API集成时如何确定GET请求中使用查询参数还是body?

问题描述 投票:0回答:1

我正在使用两个不同的 API,都使用

GET
请求,但处理请求数据的方式不同:

  1. API 1 要求在请求正文中发送数据,即使 HTTP 方法是

    GET

    示例:

    $config = [
        'method' => 'GET',
        'url' => 'http://example.com/api/endpoint',
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'body' => [
            'key1' => 'value1',
            'key2' => 'value2',
        ],
    ];
    
  2. API 2 要求将数据作为 URL 中的查询参数发送。
    示例:

    $config = [
        'method' => 'GET',
        'url' => 'http://example.com/api/endpoint',
        'headers' => [
            'Content-Type' => 'application/json',
        ],
        'query' => [
            'key1' => 'value1',
            'key2' => 'value2',
        ],
    ];
    

这两个 API 都使用

GET
方法,但它们对传递数据的要求不同。这使得决定何时使用查询参数以及何时对
GET
请求使用请求正文变得具有挑战性。

问题:

  1. 如何确定对于
    query
    请求是使用查询参数 (
    body
    ) 还是请求正文 (
    GET
    )?
  2. 即使 HTTP 规范不鼓励,
    GET
    请求接受正文中的数据是否常见或正确?
  3. 如何设计一个通用的 HTTP 客户端(例如,使用 Guzzle)来根据 API 的要求动态处理这些差异?

任何指导、最佳实践或示例,我们将不胜感激!

 $options = ['headers' => $request['headers']];

        if ($request['method'] === 'GET') {
            if ($request['isRequestRawBody']) {
                $options['body'] = json_encode($request['body']);
            } else {
                $options['query'] = $request['body'];
            }
        } else {
            $contentType = $request['headers']['Content-Type'] ?? '';

            switch ($contentType) {
                case 'application/x-www-form-urlencoded':
                    $options['form_params'] = $request['body'];
                    break;
                case 'application/json':
                    $options['json'] = $request['body'];
                    break;
                case 'multipart/form-data':
                    $options['multipart'] = array_map(function ($key, $value) {
                        return ['name' => $key, 'contents' => $value];
                    }, array_keys($request['body']), $request['body']);
                    break;
                default:
                    $options['body'] = $request['body'];
            }
        }

        return $options;
php http request get guzzle
1个回答
0
投票

GET 请求永远不应该有请求正文。 HTTP协议规范不允许这样做。您的

body
属性的内容可能会以某种方式转换为查询参数(或完全忽略)。

技术上可以通过 GET 请求提交正文,但这并未得到 HTTP/1.1 或 HTTP/2 标准的广泛支持或要求。

如果需要正文,请使用 POST、PUT 或 PATCH 方法。我见过的每个接受 JSON 输入的 API 都使用不同的方法。您可以对 JSON 进行 URL 编码,但会受到 URL 长度的限制。

GET 旨在检索数据,通常不需要在请求中提交大量信息。

如果您正在实现客户端,则可以安全地忽略 GET 请求中的正文。

RFC9112 指出:

客户端不应该在 GET 请求中生成内容,除非该请求是直接向源服务器发出的,并且该源服务器先前已在带内或带外表明此类请求具有目的并且将得到充分支持。源服务器不应该依赖私有协议来接收内容,因为 HTTP 通信的参与者通常不知道请求链上的中介。

© www.soinside.com 2019 - 2024. All rights reserved.