HTTP 클라이언트
소개
Laravel은 다른 웹 응용 프로그램과 통신하기 위해 나가는 HTTP 요청을 빠르게 만들 수 있도록 Guzzle HTTP 클라이언트를 기반으로 표현력이 풍부하고 최소한의 API를 제공합니다. Guzzle을 감싸는 Laravel의 래퍼는 가장 일반적인 사용 사례와 훌륭한 개발자 경험에 초점을 맞추고 있습니다.
요청하기
요청을 하려면 Http 파사드에서 제공하는 head, get, post, put, patch, 그리고 delete 메서드를 사용할 수 있습니다. 먼저, 다른 URL에 대한 기본적인 GET 요청을 만드는 방법을 살펴봅시다:
use Illuminate\Support\Facades\Http; $response = Http::get('http://example.com');
get 메서드는 Illuminate\Http\Client\Response 인스턴스를 반환하며, 이 인스턴스는 응답을 검사하는 데 사용할 수 있는 다양한 메서드를 제공합니다:
$response->body() : string;$response->json($key = null, $default = null) : mixed;$response->object() : object;$response->collect($key = null) : Illuminate\Support\Collection;$response->resource() : resource;$response->status() : int;$response->successful() : bool;$response->redirect(): bool;$response->failed() : bool;$response->clientError() : bool;$response->header($header) : string;$response->headers() : array;
Illuminate\Http\Client\Response 객체는 PHP ArrayAccess 인터페이스도 구현하여 응답에서 직접 JSON 응답 데이터에 접근할 수 있습니다:
return Http::get('http://example.com/users/1')['name'];
위에 나열된 응답 메서드 외에도 다음 메서드를 사용하여 응답에 지정된 상태 코드가 있는지 확인할 수 있습니다:
$response->ok() : bool; // 200 OK$response->created() : bool; // 201 Created$response->accepted() : bool; // 202 Accepted$response->noContent() : bool; // 204 No Content$response->movedPermanently() : bool; // 301 Moved Permanently$response->found() : bool; // 302 Found$response->badRequest() : bool; // 400 Bad Request$response->unauthorized() : bool; // 401 Unauthorized$response->paymentRequired() : bool; // 402 Payment Required$response->forbidden() : bool; // 403 Forbidden$response->notFound() : bool; // 404 Not Found$response->requestTimeout() : bool; // 408 Request Timeout$response->conflict() : bool; // 409 Conflict$response->unprocessableEntity() : bool; // 422 Unprocessable Entity$response->tooManyRequests() : bool; // 429 Too Many Requests$response->serverError() : bool; // 500 Internal Server Error
URI 템플릿
HTTP 클라이언트는 URI 템플릿 사양을 사용하여 요청 URL을 구성할 수도 있습니다. URI 템플릿으로 확장할 수 있는 URL 매개변수를 정의하려면 withUrlParameters 메서드를 사용할 수 있습니다:
Http::withUrlParameters([ 'endpoint' => 'https://laravel.com', 'page' => 'docs', 'version' => '11.x', 'topic' => 'validation',])->get('{+endpoint}/{page}/{version}/{topic}');
이 코드는 Http 클라이언트를 사용하여 URL 매개변수를 설정하고 GET 요청을 보내는 방법을 보여줍니다. withUrlParameters 메서드는 URL 템플릿에 사용될 매개변수를 배열 형태로 받습니다. 이 예시에서는 endpoint, page, version, topic 매개변수가 정의되어 있습니다. get 메서드는 최종 URL을 생성하기 위해 템플릿 문자열을 받습니다. 템플릿 문자열에서 {+endpoint}는 https://laravel.com로 대체되고, {page}는 docs로, {version}은 11.x로, 그리고 {topic}은 validation으로 대체됩니다. 최종적으로 요청을 보낼 URL은 https://laravel.com/docs/11.x/validation이 됩니다.
요청 덤프하기
요청을 보내기 전에 나가는 요청 인스턴스를 덤프하고 스크립트 실행을 종료하려면 요청 정의 시작 부분에 dd 메서드를 추가하면 됩니다.
return Http::dd()->get('http://example.com');
요청 데이터
물론 POST, PUT, PATCH 요청을 할 때 추가 데이터를 요청과 함께 보내는 것이 일반적이므로 이러한 메서드는 데이터 배열을 두 번째 인수로 받습니다. 기본적으로 데이터는 application/json 콘텐츠 유형을 사용하여 전송됩니다.
use Illuminate\Support\Facades\Http; $response = Http::post('http://example.com/users', [ 'name' => 'Steve', 'role' => 'Network Administrator',]);
GET 요청 쿼리 파라미터
GET 요청을 할 때 URL에 쿼리 문자열을 직접 추가하거나 get 메서드의 두 번째 인수로 키/값 쌍의 배열을 전달할 수 있습니다.
$response = Http::get('http://example.com/users', [ 'name' => 'Taylor', 'page' => 1,]);
또는 withQueryParameters 메서드를 사용할 수 있습니다.
Http::retry(3, 100)->withQueryParameters([ 'name' => 'Taylor', 'page' => 1,])->get('http://example.com/users')
Form URL 인코딩된 요청 보내기
application/x-www-form-urlencoded 콘텐츠 유형을 사용하여 데이터를 보내려면 요청하기 전에 asForm 메서드를 호출해야 합니다.
$response = Http::asForm()->post('http://example.com/users', [ 'name' => 'Sara', 'role' => 'Privacy Consultant',]);
Raw 요청 본문 보내기
요청을 할 때 raw 요청 본문을 제공하려면 withBody 메서드를 사용할 수 있습니다. 콘텐츠 유형은 메서드의 두 번째 인수를 통해 제공할 수 있습니다.
$response = Http::withBody( base64_encode($photo), 'image/jpeg')->post('http://example.com/photo');
멀티파트 요청
파일을 멀티파트 요청으로 보내려면 요청하기 전에 attach 메서드를 호출해야 합니다. 이 메서드는 파일 이름과 파일 내용을 받습니다. 필요한 경우 파일 이름으로 간주될 세 번째 인수를 제공할 수 있으며 파일과 관련된 헤더를 제공하는 데 네 번째 인수를 사용할 수 있습니다.
$response = Http::attach( 'attachment', file_get_contents('photo.jpg'), 'photo.jpg', ['Content-Type' => 'image/jpeg'])->post('http://example.com/attachments');
파일의 raw 콘텐츠를 전달하는 대신 스트림 리소스를 전달할 수 있습니다.
$photo = fopen('photo.jpg', 'r'); $response = Http::attach( 'attachment', $photo, 'photo.jpg')->post('http://example.com/attachments');
헤더
withHeaders 메서드를 사용하여 요청에 헤더를 추가할 수 있습니다. 이 withHeaders 메서드는 키/값 쌍의 배열을 받습니다.
$response = Http::withHeaders([ 'X-First' => 'foo', 'X-Second' => 'bar'])->post('http://example.com/users', [ 'name' => 'Taylor',]);
요청에 대한 응답으로 애플리케이션이 예상하는 콘텐츠 유형을 지정하기 위해 accept 메서드를 사용할 수 있습니다.
$response = Http::accept('application/json')->get('http://example.com/users');
편의를 위해 acceptJson 메서드를 사용하여 요청에 대한 응답으로 애플리케이션이 application/json 콘텐츠 유형을 예상한다고 빠르게 지정할 수 있습니다.
$response = Http::acceptJson()->get('http://example.com/users');
withHeaders 메서드는 새 헤더를 요청의 기존 헤더에 병합합니다. 필요한 경우 replaceHeaders 메서드를 사용하여 모든 헤더를 완전히 바꿀 수 있습니다.
$response = Http::withHeaders([ 'X-Original' => 'foo',])->replaceHeaders([ 'X-Replacement' => 'bar',])->post('http://example.com/users', [ 'name' => 'Taylor',]);
위 코드는 Http 클라이언트를 사용하여 HTTP POST 요청을 보내는 PHP 코드입니다.
먼저 withHeaders 메서드를 사용하여 X-Original이라는 헤더를 foo 값으로 설정합니다. 그런 다음 replaceHeaders 메서드를 사용하여 기존 헤더를 덮어쓰고, X-Replacement라는 헤더를 bar 값으로 설정합니다. 즉, X-Original 헤더는 제거되고 X-Replacement 헤더만 남게 됩니다.
마지막으로, post 메서드를 사용하여 http://example.com/users URL로 POST 요청을 보내며, 요청 바디에는 name 키에 Taylor 값을 가진 JSON 데이터가 포함됩니다. 이 요청의 응답은 $response 변수에 저장됩니다.
인증
withBasicAuth 및 withDigestAuth 메서드를 사용하여 기본 및 다이제스트 인증 자격 증명을 지정할 수 있습니다.
// 기본 인증... // 다이제스트 인증...
Bearer 토큰
요청의 Authorization 헤더에 베어러 토큰을 빠르게 추가하려면 withToken 메서드를 사용할 수 있습니다.
$response = Http::withToken('token')->post(/* ... */);
타임아웃
timeout 메서드를 사용하여 응답을 기다리는 최대 시간(초)을 지정할 수 있습니다. 기본적으로 HTTP 클라이언트는 30초 후에 타임아웃됩니다.
$response = Http::timeout(3)->get(/* ... */);
지정된 타임아웃이 초과되면 Illuminate\Http\Client\ConnectionException 인스턴스가 발생합니다.
connectTimeout 메서드를 사용하여 서버에 연결을 시도하는 동안 기다리는 최대 시간(초)을 지정할 수 있습니다.
$response = Http::connectTimeout(3)->get(/* ... */);
재시도
클라이언트 또는 서버 오류가 발생하는 경우 HTTP 클라이언트가 자동으로 요청을 재시도하도록 하려면 retry 메서드를 사용할 수 있습니다. retry 메서드는 요청을 시도해야 하는 최대 횟수와 Laravel이 시도 사이에 대기해야 하는 시간(밀리초)을 허용합니다.
$response = Http::retry(3, 100)->post(/* ... */);
시도 사이에 절전 모드로 전환할 시간(밀리초)을 수동으로 계산하려면 retry 메서드의 두 번째 인수로 클로저를 전달할 수 있습니다.
use Exception; $response = Http::retry(3, function (int $attempt, Exception $exception) { return $attempt * 100;})->post(/* ... */);
편의를 위해 retry 메서드의 첫 번째 인수로 배열을 제공할 수도 있습니다. 이 배열은 후속 시도 사이에서 절전 모드로 전환할 시간(밀리초)을 결정하는 데 사용됩니다.
$response = Http::retry([100, 200])->post(/* ... */);
필요한 경우 retry 메서드에 세 번째 인수를 전달할 수 있습니다. 세 번째 인수는 재시도를 실제로 시도해야 하는지 여부를 결정하는 callable이어야 합니다. 예를 들어, 초기 요청에서 ConnectionException이 발생하는 경우에만 요청을 재시도할 수 있습니다.
use Exception;use Illuminate\Http\Client\PendingRequest; $response = Http::retry(3, 100, function (Exception $exception, PendingRequest $request) { return $exception instanceof ConnectionException;})->post(/* ... */);
요청 시도가 실패하면 새 시도를 하기 전에 요청을 변경할 수 있습니다. retry 메서드에 제공한 callable에 제공된 요청 인수를 수정하여 이를 수행할 수 있습니다. 예를 들어, 첫 번째 시도에서 인증 오류가 반환된 경우 새 인증 토큰으로 요청을 재시도할 수 있습니다.
use Exception;use Illuminate\Http\Client\PendingRequest;use Illuminate\Http\Client\RequestException; $response = Http::withToken($this->getToken())->retry(2, 0, function (Exception $exception, PendingRequest $request) { if (! $exception instanceof RequestException || $exception->response->status() !== 401) { return false; } $request->withToken($this->getNewToken()); return true;})->post(/* ... */);
모든 요청이 실패하면 Illuminate\Http\Client\RequestException 인스턴스가 발생합니다. 이 동작을 비활성화하려면 throw 인수를 false 값으로 제공할 수 있습니다. 비활성화하면 모든 재시도가 시도된 후 클라이언트에서 수신한 마지막 응답이 반환됩니다.
$response = Http::retry(3, 100, throw: false)->post(/* ... */);
연결 문제로 인해 모든 요청이 실패하는 경우, throw 인수가 false로 설정된 경우에도 Illuminate\Http\Client\ConnectionException이 발생합니다.
오류 처리
Guzzle의 기본 동작과 달리 Laravel의 HTTP 클라이언트 래퍼는 클라이언트 또는 서버 오류(400 및 500 수준 서버 응답)에 대한 예외를 발생시키지 않습니다. successful, clientError 또는 serverError 메서드를 사용하여 이러한 오류 중 하나가 반환되었는지 확인할 수 있습니다.
// 상태 코드가 >= 200이고 < 300인지 확인...$response->successful(); // 상태 코드가 >= 400인지 확인...$response->failed(); // 응답에 400 수준 상태 코드가 있는지 확인...$response->clientError(); // 응답에 500 수준 상태 코드가 있는지 확인...$response->serverError(); // 클라이언트 또는 서버 오류가 있는 경우 지정된 콜백을 즉시 실행...$response->onError(callable $callback);
예외 발생
응답 인스턴스가 있고 응답 상태 코드가 클라이언트 또는 서버 오류를 나타내는 경우 Illuminate\Http\Client\RequestException 인스턴스를 발생시키려면 throw 또는 throwIf 메서드를 사용할 수 있습니다.
use Illuminate\Http\Client\Response; $response = Http::post(/* ... */); // 클라이언트 또는 서버 오류가 발생한 경우 예외 발생...$response->throw(); // 오류가 발생했고 지정된 조건이 true인 경우 예외 발생...$response->throwIf($condition); // 오류가 발생했고 지정된 클로저가 true로 확인되는 경우 예외 발생...$response->throwIf(fn (Response $response) => true); // 오류가 발생했고 지정된 조건이 false인 경우 예외 발생...$response->throwUnless($condition); // 오류가 발생했고 지정된 클로저가 false로 확인되는 경우 예외 발생...$response->throwUnless(fn (Response $response) => false); // 응답에 특정 상태 코드가 있는 경우 예외 발생...$response->throwIfStatus(403); // 응답에 특정 상태 코드가 없는 경우 예외 발생...$response->throwUnlessStatus(200); return $response['user']['id'];
Illuminate\Http\Client\RequestException 인스턴스에는 반환된 응답을 검사할 수 있는 public $response 속성이 있습니다.
오류가 발생하지 않으면 throw 메서드는 응답 인스턴스를 반환하여 throw 메서드에 다른 작업을 연결할 수 있습니다.
return Http::post(/* ... */)->throw()->json();
예외가 발생하기 전에 몇 가지 추가 논리를 수행하려면 throw 메서드에 클로저를 전달할 수 있습니다. 클로저가 호출된 후 예외가 자동으로 발생하므로 클로저 내에서 예외를 다시 발생시킬 필요가 없습니다.
use Illuminate\Http\Client\Response;use Illuminate\Http\Client\RequestException; return Http::post(/* ... */)->throw(function (Response $response, RequestException $e) { // ...})->json();
기본적으로 RequestException 메시지는 로깅되거나 보고될 때 120자로 잘립니다. 이 동작을 사용자 지정하거나 비활성화하려면 bootstrap/app.php 파일에서 애플리케이션의 예외 처리 동작을 구성할 때 truncateRequestExceptionsAt 및 dontTruncateRequestExceptions 메서드를 활용할 수 있습니다.
->withExceptions(function (Exceptions $exceptions) { // 요청 예외 메시지를 240자로 자르기... $exceptions->truncateRequestExceptionsAt(240); // 요청 예외 메시지 자르기 비활성화... $exceptions->dontTruncateRequestExceptions();})
Guzzle 미들웨어
Laravel의 HTTP 클라이언트는 Guzzle에서 제공되므로 Guzzle 미들웨어를 활용하여 나가는 요청을 조작하거나 들어오는 응답을 검사할 수 있습니다. 나가는 요청을 조작하려면 withRequestMiddleware 메서드를 통해 Guzzle 미들웨어를 등록합니다.
use Illuminate\Support\Facades\Http;use Psr\Http\Message\RequestInterface; $response = Http::withRequestMiddleware( function (RequestInterface $request) { return $request->withHeader('X-Example', 'Value'); })->get('http://example.com');
마찬가지로 withResponseMiddleware 메서드를 통해 미들웨어를 등록하여 들어오는 HTTP 응답을 검사할 수 있습니다.
use Illuminate\Support\Facades\Http;use Psr\Http\Message\ResponseInterface; $response = Http::withResponseMiddleware( function (ResponseInterface $response) { $header = $response->getHeader('X-Example'); // ... return $response; })->get('http://example.com');
글로벌 미들웨어
경우에 따라 모든 나가는 요청 및 들어오는 응답에 적용되는 미들웨어를 등록할 수 있습니다. 이를 달성하려면 globalRequestMiddleware 및 globalResponseMiddleware 메서드를 사용할 수 있습니다. 일반적으로 이러한 메서드는 애플리케이션의 AppServiceProvider의 boot 메서드에서 호출해야 합니다.
use Illuminate\Support\Facades\Http; Http::globalRequestMiddleware(fn ($request) => $request->withHeader( 'User-Agent', 'Example Application/1.0')); Http::globalResponseMiddleware(fn ($response) => $response->withHeader( 'X-Finished-At', now()->toDateTimeString()));
Guzzle 옵션
withOptions 메소드를 사용하여 발신 요청에 대한 추가 Guzzle 요청 옵션을 지정할 수 있습니다. withOptions 메소드는 키/값 쌍의 배열을 허용합니다.
$response = Http::withOptions([ 'debug' => true,])->get('http://example.com/users');
글로벌 옵션
모든 발신 요청에 대한 기본 옵션을 구성하려면 globalOptions 메소드를 활용할 수 있습니다. 일반적으로 이 메소드는 애플리케이션의 AppServiceProvider의 boot 메소드에서 호출해야 합니다.
use Illuminate\Support\Facades\Http; /** * Bootstrap any application services. */public function boot(): void{ Http::globalOptions([ 'allow_redirects' => false, ]);}
동시 요청
때로는 여러 HTTP 요청을 동시에 보내고 싶을 수 있습니다. 다시 말해, 요청을 순차적으로 보내는 대신 동시에 여러 요청을 보내고 싶을 수 있습니다. 이는 느린 HTTP API와 상호 작용할 때 상당한 성능 향상을 가져올 수 있습니다.
다행히도 pool 메서드를 사용하여 이를 수행할 수 있습니다. pool 메서드는 Illuminate\Http\Client\Pool 인스턴스를 받는 클로저를 허용하여 요청 풀에 요청을 쉽게 추가하여 디스패치할 수 있습니다.
use Illuminate\Http\Client\Pool;use Illuminate\Support\Facades\Http; $responses = Http::pool(fn (Pool $pool) => [ $pool->get('http://localhost/first'), $pool->get('http://localhost/second'), $pool->get('http://localhost/third'),]); return $responses[0]->ok() && $responses[1]->ok() && $responses[2]->ok();
보시다시피 각 응답 인스턴스는 풀에 추가된 순서에 따라 액세스할 수 있습니다. 원하는 경우 as 메서드를 사용하여 요청 이름을 지정할 수 있으며, 이를 통해 해당 응답에 이름으로 액세스할 수 있습니다.
use Illuminate\Http\Client\Pool;use Illuminate\Support\Facades\Http; $responses = Http::pool(fn (Pool $pool) => [ $pool->as('first')->get('http://localhost/first'), $pool->as('second')->get('http://localhost/second'), $pool->as('third')->get('http://localhost/third'),]); return $responses['first']->ok();
동시 요청 사용자 지정
pool 메서드는 withHeaders 또는 middleware 메서드와 같은 다른 HTTP 클라이언트 메서드와 연결할 수 없습니다. 풀링된 요청에 사용자 지정 헤더 또는 미들웨어를 적용하려면 풀의 각 요청에서 해당 옵션을 구성해야 합니다.
use Illuminate\Http\Client\Pool;use Illuminate\Support\Facades\Http; $headers = [ 'X-Example' => 'example',]; $responses = Http::pool(fn (Pool $pool) => [ $pool->withHeaders($headers)->get('http://laravel.test/test'), $pool->withHeaders($headers)->get('http://laravel.test/test'), $pool->withHeaders($headers)->get('http://laravel.test/test'),]);
매크로
라라벨 HTTP 클라이언트는 "매크로"를 정의할 수 있게 해주며, 이는 애플리케이션 전체에서 서비스와 상호 작용할 때 일반적인 요청 경로와 헤더를 구성하기 위한 유연하고 표현력이 풍부한 메커니즘 역할을 할 수 있습니다. 시작하려면 애플리케이션의 App\Providers\AppServiceProvider 클래스의 boot 메서드 내에서 매크로를 정의할 수 있습니다.
use Illuminate\Support\Facades\Http; /** * 애플리케이션 서비스 부트스트랩. */public function boot(): void{ Http::macro('github', function () { return Http::withHeaders([ 'X-Example' => 'example', ])->baseUrl('https://github.com'); });}
매크로가 구성되면, 애플리케이션 어디에서든 이를 호출하여 지정된 구성으로 보류 중인 요청을 생성할 수 있습니다.
$response = Http::github()->get('/');
테스트
많은 Laravel 서비스는 테스트를 쉽고 표현력 있게 작성하는 데 도움이 되는 기능을 제공하며, Laravel의 HTTP 클라이언트도 예외는 아닙니다. Http 파사드의 fake 메서드를 사용하면 요청이 이루어질 때 HTTP 클라이언트가 스텁/더미 응답을 반환하도록 지시할 수 있습니다.
응답 페이킹
예를 들어 모든 요청에 대해 비어 있는 200 상태 코드 응답을 반환하도록 HTTP 클라이언트에 지시하려면 인수 없이 fake 메서드를 호출할 수 있습니다.
use Illuminate\Support\Facades\Http; Http::fake(); $response = Http::post(/* ... */);
특정 URL 페이킹
또는 fake 메서드에 배열을 전달할 수 있습니다. 배열의 키는 페이크하려는 URL 패턴과 해당 응답을 나타내야 합니다. * 문자는 와일드카드 문자로 사용할 수 있습니다. 페이크되지 않은 URL에 대한 요청은 실제로 실행됩니다. Http 파사드의 response 메서드를 사용하여 이러한 엔드포인트에 대한 스텁/페이크 응답을 구성할 수 있습니다.
Http::fake([ // GitHub 엔드포인트에 대한 JSON 응답 스텁... 'github.com/*' => Http::response(['foo' => 'bar'], 200, $headers), // Google 엔드포인트에 대한 문자열 응답 스텁... 'google.com/*' => Http::response('Hello World', 200, $headers),]);
일치하지 않는 모든 URL을 스텁하는 폴백 URL 패턴을 지정하려면 단일 * 문자를 사용할 수 있습니다.
Http::fake([ // GitHub 엔드포인트에 대한 JSON 응답 스텁... 'github.com/*' => Http::response(['foo' => 'bar'], 200, ['Headers']), // 다른 모든 엔드포인트에 대한 문자열 응답 스텁... '*' => Http::response('Hello World', 200, ['Headers']),]);
편의를 위해 간단한 문자열, JSON 및 빈 응답은 문자열, 배열 또는 정수를 응답으로 제공하여 생성할 수 있습니다.
Http::fake([ 'google.com/*' => 'Hello World', 'github.com/*' => ['foo' => 'bar'], 'chatgpt.com/*' => 200,]);
연결 예외 페이킹
경우에 따라 HTTP 클라이언트가 요청을 시도할 때 Illuminate\Http\Client\ConnectionException을 만나는 경우 애플리케이션의 동작을 테스트해야 할 수 있습니다. failedConnection 메서드를 사용하여 HTTP 클라이언트가 연결 예외를 발생시키도록 지시할 수 있습니다.
Http::fake([ 'github.com/*' => Http::failedConnection(),]);
응답 시퀀스 페이킹
경우에 따라 단일 URL이 특정 순서로 일련의 페이크 응답을 반환해야 할 수 있습니다. Http::sequence 메서드를 사용하여 응답을 빌드함으로써 이를 수행할 수 있습니다.
Http::fake([ // GitHub 엔드포인트에 대한 일련의 응답 스텁... 'github.com/*' => Http::sequence() ->push('Hello World', 200) ->push(['foo' => 'bar'], 200) ->pushStatus(404),]);
응답 시퀀스의 모든 응답이 소비되면 추가 요청으로 인해 응답 시퀀스에서 예외가 발생합니다. 시퀀스가 비어 있을 때 반환되어야 하는 기본 응답을 지정하려면 whenEmpty 메서드를 사용할 수 있습니다.
Http::fake([ // GitHub 엔드포인트에 대한 일련의 응답 스텁... 'github.com/*' => Http::sequence() ->push('Hello World', 200) ->push(['foo' => 'bar'], 200) ->whenEmpty(Http::response()),]);
일련의 응답을 페이크하고 싶지만 페이크해야 할 특정 URL 패턴을 지정할 필요가 없는 경우 Http::fakeSequence 메서드를 사용할 수 있습니다.
Http::fakeSequence() ->push('Hello World', 200) ->whenEmpty(Http::response());
페이크 콜백
특정 엔드포인트에 대해 반환할 응답을 결정하는 데 더 복잡한 논리가 필요한 경우 클로저를 fake 메서드에 전달할 수 있습니다. 이 클로저는 Illuminate\Http\Client\Request의 인스턴스를 받고 응답 인스턴스를 반환해야 합니다. 클로저 내에서 반환할 응답 유형을 결정하는 데 필요한 논리를 수행할 수 있습니다.
use Illuminate\Http\Client\Request; Http::fake(function (Request $request) { return Http::response('Hello World', 200);});
의도하지 않은 요청 방지
HTTP 클라이언트를 통해 전송된 모든 요청이 개별 테스트 또는 전체 테스트 스위트에서 페이크되었는지 확인하려면 preventStrayRequests 메서드를 호출할 수 있습니다. 이 메서드를 호출한 후에는 해당 페이크 응답이 없는 요청은 실제 HTTP 요청을 하는 대신 예외를 발생시킵니다.
use Illuminate\Support\Facades\Http; Http::preventStrayRequests(); Http::fake([ 'github.com/*' => Http::response('ok'),]); // "ok" 응답이 반환됩니다...Http::get('https://github.com/laravel/framework'); // 예외가 발생합니다...Http::get('https://laravel.com');
요청 검사
응답을 페이크할 때 애플리케이션이 올바른 데이터 또는 헤더를 보내고 있는지 확인하기 위해 클라이언트가 받는 요청을 검사하려는 경우가 있습니다. Http::fake를 호출한 후 Http::assertSent 메서드를 호출하여 이를 수행할 수 있습니다.
assertSent 메서드는 Illuminate\Http\Client\Request 인스턴스를 수신하고 요청이 예상과 일치하는지 여부를 나타내는 부울 값을 반환해야 하는 클로저를 허용합니다. 테스트를 통과하려면 주어진 예상과 일치하는 하나 이상의 요청이 발행되어야 합니다.
use Illuminate\Http\Client\Request;use Illuminate\Support\Facades\Http; Http::fake(); Http::withHeaders([ 'X-First' => 'foo',])->post('http://example.com/users', [ 'name' => 'Taylor', 'role' => 'Developer',]); Http::assertSent(function (Request $request) { return $request->hasHeader('X-First', 'foo') && $request->url() == 'http://example.com/users' && $request['name'] == 'Taylor' && $request['role'] == 'Developer';});
필요한 경우 assertNotSent 메서드를 사용하여 특정 요청이 전송되지 않았는지 확인할 수 있습니다.
use Illuminate\Http\Client\Request;use Illuminate\Support\Facades\Http; Http::fake(); Http::post('http://example.com/users', [ 'name' => 'Taylor', 'role' => 'Developer',]); Http::assertNotSent(function (Request $request) { return $request->url() === 'http://example.com/posts';});
assertSentCount 메서드를 사용하여 테스트 중에 얼마나 많은 요청이 "전송"되었는지 확인할 수 있습니다.
Http::fake(); Http::assertSentCount(5);
또는 assertNothingSent 메서드를 사용하여 테스트 중에 요청이 전송되지 않았는지 확인할 수 있습니다.
Http::fake(); Http::assertNothingSent();
요청 / 응답 기록
recorded 메서드를 사용하여 모든 요청과 해당 응답을 수집할 수 있습니다. recorded 메서드는 Illuminate\Http\Client\Request 및 Illuminate\Http\Client\Response 인스턴스를 포함하는 배열 모음을 반환합니다.
Http::fake([ 'https://laravel.com' => Http::response(status: 500), 'https://nova.laravel.com/' => Http::response(),]); Http::get('https://laravel.com');Http::get('https://nova.laravel.com/'); $recorded = Http::recorded(); [$request, $response] = $recorded[0];
또한, recorded 메소드는 클로저를 받아들이며, 이 클로저는 Illuminate\Http\Client\Request 와 Illuminate\Http\Client\Response 인스턴스를 받아 사용자의 기대에 따라 요청/응답 쌍을 필터링하는 데 사용할 수 있습니다:
use Illuminate\Http\Client\Request;use Illuminate\Http\Client\Response; Http::fake([ 'https://laravel.com' => Http::response(status: 500), 'https://nova.laravel.com/' => Http::response(),]); Http::get('https://laravel.com');Http::get('https://nova.laravel.com/'); $recorded = Http::recorded(function (Request $request, Response $response) { return $request->url() !== 'https://laravel.com' && $response->successful();});
이벤트
Laravel은 HTTP 요청을 보내는 과정 중에 세 가지 이벤트를 발생시킵니다. RequestSending 이벤트는 요청이 보내지기 전에 발생하고, ResponseReceived 이벤트는 주어진 요청에 대한 응답을 받은 후에 발생합니다. ConnectionFailed 이벤트는 주어진 요청에 대해 응답을 받지 못했을 때 발생합니다.
RequestSending 및 ConnectionFailed 이벤트는 모두 Illuminate\Http\Client\Request 인스턴스를 검사하는 데 사용할 수 있는 public $request 속성을 포함합니다. 마찬가지로 ResponseReceived 이벤트는 Illuminate\Http\Client\Response 인스턴스를 검사하는 데 사용할 수 있는 $request 속성과 $response 속성을 모두 포함합니다. 애플리케이션 내에서 이러한 이벤트에 대한 이벤트 리스너를 만들 수 있습니다.
use Illuminate\Http\Client\Events\RequestSending; class LogRequest{ /** * Handle the given event. */ public function handle(RequestSending $event): void { // $event->request ... }}