From 5b42ceec9490d6bb697a80de86cbdf74ef4f74a9 Mon Sep 17 00:00:00 2001 From: Paulo Margarido Date: Thu, 10 Feb 2022 17:00:07 -0500 Subject: [PATCH] Allow full paths in REST requests --- CHANGELOG.md | 1 + docs/usage/rest.md | 6 +++--- src/Clients/Http.php | 15 ++++++++++----- src/Clients/Rest.php | 13 ++++++++++--- tests/Clients/RestTest.php | 23 +++++++++++++++++++++++ 5 files changed, 47 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 370f08e1..9ad9fc13 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ and adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). ### Added - [#134](https://github.com/Shopify/shopify-php-api/pull/134) ⚠️ [Breaking] Add support for PHP 8.1 and remove 7.3 from the supported list, since it's no longer supported +- [#136](https://github.com/Shopify/shopify-php-api/pull/136) Allow full paths in REST requests ### Fixed diff --git a/docs/usage/rest.md b/docs/usage/rest.md index 5c4f0e7d..66c3e7b4 100644 --- a/docs/usage/rest.md +++ b/docs/usage/rest.md @@ -12,12 +12,12 @@ REST uses `get`, `post`, `put`, and `delete` requests to retrieve, create, updat | Parameter | Type | Required? | Default Value | Notes | |:----------|:----------------|:---------:|:----------------:|:-------------------------------------------------| -| path | string | Yes | | The URL path to request | -| body | string or array | No | null | Only `Post`, and `put` methods can have body | +| path | string | Yes | | The requested API endpoint path. This can be one of two formats: | +| body | string or array | No | null | Only `post`, and `put` methods can have body | | headers | array | No | [] | Any extra headers to send along with the request | | query | array | No | [] | Query parameters as an associative array | | tries | int | No | null | How many times to attempt the request | -| dataType | No | No | `DATA_TYPE_JSON` | Only `Post`, and `put` methods can have body | +| dataType | No | No | `DATA_TYPE_JSON` | Only `post`, and `put` methods can have body | In the following example we will retrieve a list of products from a shop using `Shopify\Clients\Rest` class. diff --git a/src/Clients/Http.php b/src/Clients/Http.php index bba2fbc3..ba235111 100644 --- a/src/Clients/Http.php +++ b/src/Clients/Http.php @@ -163,14 +163,10 @@ protected function request( $client = Context::$HTTP_CLIENT_FACTORY->client(); - if (strpos($path, '/') !== 0) { - $path = "/$path"; - } - $url = (new Uri()) ->withScheme('https') ->withHost($this->domain) - ->withPath($path) + ->withPath($this->getRequestPath($path)) ->withQuery(http_build_query($query)); $request = new Request($method, $url, $headers); @@ -217,6 +213,15 @@ protected function request( return $response; } + protected function getRequestPath(string $path): string + { + if (strpos($path, '/') !== 0) { + $path = "/$path"; + } + + return $path; + } + /** * Logs an API deprecation for the given URL to the app's logged, if one was given. * diff --git a/src/Clients/Rest.php b/src/Clients/Rest.php index 85130266..8f707f0c 100644 --- a/src/Clients/Rest.php +++ b/src/Clients/Rest.php @@ -45,7 +45,7 @@ protected function request( $headers[HttpHeaders::X_SHOPIFY_ACCESS_TOKEN] = Context::$IS_PRIVATE_APP ? Context::$API_SECRET_KEY : $this->accessToken; - $response = parent::request($this->getRestPath($path), $method, $body, $headers, $query, $tries, $dataType); + $response = parent::request($path, $method, $body, $headers, $query, $tries, $dataType); return new RestResponse( $response->getStatusCode(), @@ -57,10 +57,17 @@ protected function request( ); } - private function getRestPath(string $path): string + protected function getRequestPath(string $path): string { + $path = parent::getRequestPath($path); + $path = preg_replace("/\.json$/", "", $path) . ".json"; + $apiVersion = Context::$API_VERSION; - return "admin/api/$apiVersion/$path.json"; + if (strpos($path, "/admin") !== 0) { + $path = "/admin/api/$apiVersion$path"; + } + + return $path; } /** diff --git a/tests/Clients/RestTest.php b/tests/Clients/RestTest.php index 659a32f3..600e2e9c 100644 --- a/tests/Clients/RestTest.php +++ b/tests/Clients/RestTest.php @@ -84,6 +84,29 @@ public function testCanMakeGetRequest() $this->assertThat($response, new HttpResponseMatcher(200, [], $this->successResponse)); } + public function testAllowsFullPaths() + { + $headers = ['X-Test-Header' => 'test_value']; + + $client = new Rest($this->domain, 'dummy-token'); + + $this->mockTransportRequests([ + new MockRequest( + $this->buildMockHttpResponse(200, $this->successResponse), + "https://$this->domain/admin/custom_path.json", + 'GET', + "Shopify Admin API Library for PHP v$this->version", + ['X-Test-Header: test_value', 'X-Shopify-Access-Token: dummy-token'], + null, + null, + false, + ), + ]); + + $response = $client->get('/admin/custom_path', $headers); + $this->assertThat($response, new HttpResponseMatcher(200, [], $this->successResponse)); + } + public function testCanMakeGetRequestWithPathInQuery() { $client = new Rest($this->domain, 'dummy-token');