모두들 그 동안 잘 지내셨나요? 코로나 때문에 다들 힘드실 것 같아요 ㅠ
아직 완전히 끝낸 건 아니지만 번역 작업이 어느 정도 진행되서 다시 1일 1식 라라벨을 재개합니다! 너무 오래 기다리셨어요 ㅠㅠ
앞으로도 꾸준히 성실하게 라라벨을 사용하는데 도움이 되는 글을 하루 한 편씩 전달해드리도록 하겠습니다. 저 말고도 함께 1일 1식 라라벨 컨텐츠를 만들 분들이 함께 하니 기대해주세요.
오늘 준비한 내용은 라라벨 7에 새로 추가된 HTTP 클라이언트입니다. 재밋게 봐주세요!
라라벨 HTTP 클라이언트는 Guzzle HTTP 클라이언트를 기반으로 하되 자주 쓰는 기능만 추리고, 더 사용하기 편하게 만든 도구입니다. 주로 외부 애플리케이션에 HTTP 요청을 보낼 때 사용합니다.
Guzzle HTTP 클라이언트에 의존하기 때문에 컴포저로 애플리케이션에 Guzzle HTTP 클라이언트를 설치해야 사용할 수 있습니다.
저 처럼 어차피 외부에 요청을 보내기 위해 Guzzle을 설치해서 썼던 사람이라면 왠만한 건 라라벨 HTTP 클라이언트로 처리하고 복잡한 기능이 필요하면 Guzzle을 사용하는 식으로 활용하면 될 것 같습니다. Guzzle이 아닌 다른 HTTP 클라이언트를 사용하고 있었다면 기존에 쓰던 것을 유지할 지 갈아탈 지 한 번쯤 검토해보는 것도 좋을 것 같네요.
사용법은 공식 문서에 잘 안내되어 있으니 따로 설명할 필요는 없을 것 같습니다. 써볼까? 싶은 분들은 꼭 공식 문서를 한 번 읽어보시길 권해드려요. 이 글에서는 기존에 사용하던 도구인 Guzzle에 비해 얼마나 편해졌는지를 위주로 정리해보도록 하겠습니다.
// Guzzle
$client = new GuzzleHttp\Client();
$res = $client->get('https://laravel.com');
// 라라벨 HTTP
$response = Http::get('https://laravel.com');
퍼사드를 이용해서 인스턴스화 하는 단계를 줄일 수 있습니다. 별 것 아닙니다만. :)
라라벨 HTTP 클라이언트의 get 메서드가 반환하는 Illuminate\Http\Client\Response는 ArrayAccess 인터페이스를 구현하고 있어서 JSON 응답 데이터에 접근하기가 Guzzle에 비해 편리합니다.
// Guzzle
$client = new GuzzleHttp\Client();
$res = $client->get('http://test.com/users/1');
return $response->json()['name'];
// 라라벨 HTTP
return Http::get('http://test.com/users/1')['name'];
application/x-www-form-urlencoded 컨텐트 타입으로 데이터를 전송하고 싶은 경우, Guzzle은 ‘form_parmas’에 배열로 데이터를 담아 전송하면 되고, 라라벨 HTTP는 asForm() 메서드를 사용하면 됩니다.
// Guzzle
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'http://test.com/users', [
'form_params' => [
'name' => 'Sara',
'role' => 'Privacy Consultant',
]
]);
// 라라벨 HTTP
$response = Http::asForm()->post('http://test.com/users', [
'name' => 'Sara',
'role' => 'Privacy Consultant',
]);
Guzzle과 라라벨 HTTP 모두 문자열과 스트림으로 파일을 전달할 수 있습니다. Guzzle로 파일을 전송할 때는 ‘multipart’에 배열로 데이터를 담아 전송하면 되고, 라라벨 HTTP는 attach() 메서드를 사용하면 됩니다.
// Guzzle 문자열 이용
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'http://httpbin.org/post', [
'multipart' => [
[
'name' => 'field_name',
'contents' => 'abc'
'filename' => 'filename.txt',
]
]
]);
// 라라벨 HTTP 문자열 이용
$response = Http::attach(
'attachment', file_get_contents('photo.jpg'), 'photo.jpg'
)->post('http://test.com/attachments');
// Guzzle 스트림 이용
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'http://httpbin.org/post', [
'multipart' => [
[
'name' => 'file_name',
'contents' => fopen('/path/to/file', 'r'),
'filename' => 'filename.txt',
],
]
]);
// 라라벨 HTTP 스트림 이용
$photo = fopen('photo.jpg', 'r');
$response = Http::attach(
'attachment', $photo, 'photo.jpg'
)->post('http://test.com/attachments');
// Guzzle 기본
$response = $client->request('GET', '/get', ['auth' => ['username', 'password']]);
// Guzzle 다이제스트
$response = $client->request('GET', '/get', [
'auth' => ['username', 'password', 'digest']
]);
// Guzzle Bearer
$response = $client->request('GET', '/get', [
'headers' => [
'Authorization' => 'Bearer' . $token,
'Accept' => 'application/json',
]
]);
// 라라벨 HTTP 기본
$response = Http::withBasicAuth('taylor@laravel.com', 'secret')->post(...);
// 라라벨 HTTP 다이제스트
$response = Http::withDigestAuth('taylor@laravel.com', 'secret')->post(...);
// 라라벨 HTTP Bearer
$response = Http::withToken('token')->post(...);
Guzzle은 내장된 RetryMiddleware를 사용하거나, caseyamcl/guzzle_retry_middleware 같은 외부 패키지를 사용해서 재시도를 설정할 수 있습니다. 언뜻 보기에 라라벨 HTTP 보다 편하게 설정할 수 있는 것 처럼 보이진 않네요.
// 라라벨 HTTP
$response = Http::retry(3, 100)->post(...);
Guzzle은 외부 서버에서 에러가 발생해도 예외를 던지지만, 라라벨 HTTP는 그렇지 않습니다. 이건 어떤 방식이 더 편리한건지 잘 모르겠네요.
기존에는 응답을 속이기 위해 직접 모킹해야 했습니다. 라라벨 HTTP는 테스트에 활용할 수 있는 여러 편의 기능을 제공합니다. 이 부분에 대해서는 라라벨 HTTP가 압승인 듯 합니다. 간단히 비교하면 아래와 같습니다. 더 많은 기능이 있으니 관심있으시면 공식 메뉴얼을 참고하세요.
// Guzzle
$mock = $this->mock(Client::class);
$mock->shouldReceive('send')
->andReturn(new Response(
$status = 200,
$headers = [],
['foo' => 'bar']
));
// 라라벨 HTTP
Http::fake([
// 깃헙 엔드포인트용 JSON 응답 스텁...
'github.com/*' => Http::response(['foo' => 'bar'], 200, ['Headers']),
// 구글 엔드포인트용 문자열 응답 스텁...
'google.com/*' => Http::response('Hello World', 200, ['Headers']),
]);
기존에 Guzzle(또는 다른 HTTP 클라이언트 패키지)를 사용하는 것에 비해 어떤 면에서 편리해졌을까 하는 궁금증으로 글을 시작했습니다. 하나씩 정리해보니 확실히 더 편리해보이네요. 서두에 말씀드린 것 처럼 어차피 라라벨 HTTP 클라이언트를 사용하기 위해선 Guzzle을 설치해야 하기 때문에, 좀 더 손쉽게 사용할 수 있는 HTTP 클라이언트를 우선 이용하고 이것으로 해결되지 않는 상황은 Guzzle로 해결하면 어떨까 싶습니다.
메쉬 코리아 개발자. 바쁜 팀장님 대신 알려주는 신입 PHP 개발자 안내서를 쓰고, 클린 아키텍처 인 PHP를 번역했습니다. 처음부터 제대로 배우는 라라벨(Laravel Up & Running 2nd Edition)을 번역했습니다.