라라벨 7의 새로운 기능, HTTP 클라이언트

6 minute read

라라벨 HTTP 클라이언트는 Guzzle HTTP 클라이언트를 기반으로 하되 자주 쓰는 기능만 추리고, 더 사용하기 편하게 만든 도구입니다.

라라벨 7

주로 외부 애플리케이션에 HTTP 요청을 보낼 때 사용합니다.

Guzzle HTTP 클라이언트에 의존하기 때문에 컴포저로 애플리케이션에 Guzzle HTTP 클라이언트를 설치해야 사용할 수 있습니다.

저 처럼 어차피 외부에 요청을 보내기 위해 Guzzle을 설치해서 썼던 사람이라면 왠만한 건 라라벨 HTTP 클라이언트로 처리하고 복잡한 기능이 필요하면 Guzzle을 사용하는 식으로 활용하면 될 것 같습니다. Guzzle이 아닌 다른 HTTP 클라이언트를 사용하고 있었다면 기존에 쓰던 것을 유지할 지 갈아탈 지 한 번쯤 검토해보는 것도 좋을 것 같네요.

Guzzle과 간단한 비교

사용법은 공식 문서에 잘 안내되어 있으니 따로 설명할 필요는 없을 것 같습니다. 써볼까? 싶은 분들은 꼭 공식 문서를 한 번 읽어보시길 권해드려요. 이 글에서는 기존에 사용하던 도구인 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로 해결하면 어떨까 싶습니다.

Comments