diff --git a/src/Api/Serializer/RestSerializer.php b/src/Api/Serializer/RestSerializer.php index 7ec7dc71de..e0dfaebd59 100644 --- a/src/Api/Serializer/RestSerializer.php +++ b/src/Api/Serializer/RestSerializer.php @@ -243,10 +243,11 @@ function (array $matches) use ($varDefinitions) { } } - if (!$isModifiedModel + if ((!empty($relative) && $relative !== '/') + && !$isModifiedModel && $serviceName !== 's3' ) { - $relative = $this->prependPath($relative, $path); + $this->normalizePath($path); } // If endpoint has path, remove leading '/' to preserve URI resolution. @@ -310,31 +311,17 @@ private function getVarDefinitions($command, $args) } /** - * If non-empty path with at least one segment present, compare - * with relative and prepend if starting segments are not duplicated + * Appends trailing slash to non-empty paths with at least one segment + * to ensure proper URI resolution * - * @param string $relative * @param string $path * - * @return string + * @return void */ - private function prependPath(string $relative, string $path): string + private function normalizePath(string $path): void { - if (empty($relative) || $relative === '/' - || empty($path) || $path === '/' - ) { - return $relative; + if (!empty($path) && $path !== '/' && substr($path, -1) !== '/') { + $this->endpoint = $this->endpoint->withPath($path . '/'); } - - $normalizedPath = rtrim($path, '/'); - $normalizedRelative = ltrim($relative, '/'); - - // Check if $relative starts with $path - if (strpos($normalizedRelative, ltrim($normalizedPath, '/')) === 0) { - // $relative already starts with $path, return $relative - return $relative; - } - - return $normalizedPath . '/' . $normalizedRelative; } } diff --git a/tests/Api/Serializer/RestJsonSerializerTest.php b/tests/Api/Serializer/RestJsonSerializerTest.php index 0660fde503..d0a20fe6b5 100644 --- a/tests/Api/Serializer/RestJsonSerializerTest.php +++ b/tests/Api/Serializer/RestJsonSerializerTest.php @@ -220,26 +220,6 @@ public function testPreparesRequestsWithEndpointWithRequestUriAndPath(): void ); } - /** - * Simulates a custom endpoint provided with a starting path segment matching the - * modeled `RequestUri` starting path segment - */ - public function testPreparesRequestsWithEndpointWithDuplicateRequestUriAndPath(): void - { - $request = $this->getPathEndpointRequest( - 'requestUriOperation', - ['PathSegment' => 'bar', 'baz' => 'bar'], - ['path' => 'foo'] - ); - $this->assertSame('POST', $request->getMethod()); - $this->assertSame('http://foo.com/foo/bar', (string) $request->getUri()); - $this->assertSame('{"baz":"bar"}', (string) $request->getBody()); - $this->assertSame( - 'application/json', - $request->getHeaderLine('Content-Type') - ); - } - public function testPreparesRequestsWithBlobButNoForcedContentType() { $request = $this->getRequest('bar', ['baz' => 'bar']);