테일러 오트웰은 왜 API 라우트를 routes/web.php에 작성했을까? free

2019-07-08

몇 주 전인 2019년 6월 24벨 데는 트위터 계정이 다음과 같은 트윗을 올렸다.

스크린샷 2019-07-08 오후 11.02.34.png



벨은 구조를 어떻게 가져가야한다는 엄격한 룰이 존재하지 않는다. 심지어 벨 호이즌 같은 공 프로젝트를 봐도 테러가 모든 API 우트를 routes/web.php에 넣었다. routes/api.php이 따로 존재하지 않는다.



그러자 테러 오트웰이 이 트윗이 잘못되었다며 반박 트윗을 올렸다.

스크린샷 2019-07-08 오후 11.06.56.png



안녕하세요. 이 트윗을 잘못되었습니다. 미들웨어 그룹들의 차이를 조사해보면 왜 우트를 거기에 넣었는지 알 수 있을 겁니다.



이에 벨 데리는 자신이 표현을 잘못했다고 사과하며, 벨의 자유도가 높아서 좋다고 이야기하고 싶었던 것이고 했다.

스크린샷 2019-07-08 오후 11.07.46.png


어떤 미들웨어 그룹이길래


미들웨어 그룹이 어떻길래 저렇게 얘기했을까 살펴보기로 했다. 설치해보니 벨 호이즌은 반적인 벨과 구조가 조금 다르다. 최신 버전 벨에서는 app/Http/Middleware/Kernel.php에 미들웨어 그룹이 선언되어 있다.


protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],

'api' => [
'throttle:60,1',
'bindings',
],

한편 호이즌은 src/HorizonServiceProvider.php에 다음과 같이 정의되어 있다.


public function boot()
{
$this->registerEvents();
$this->registerRoutes();
$this->registerResources();
$this->defineAssetPublishing();
}

...

protected function registerRoutes()
{
Route::group([
'domain' => config('horizon.domain', null),
'prefix' => config('horizon.path'),
'namespace' => 'Laravel\Horizon\Http\Controllers',
'middleware' => config('horizon.middleware', 'web'),
], function () {
$this->loadRoutesFrom(__DIR__.'/../routes/web.php');
});
}

routes/web.php에 등록된 모든 우트는 config/horizon.phpmiddleware 항목에 해당하는 미들웨어가 적용되거나, 설정된 값이 없으면 web 미들웨어가 적용되도록 되어있다.


config/horizon.php를 열어보면 다음과 같이 web 미들웨어가 설정되어 있다.


'middleware' => ['web'],

그냥 web 미들웨어 그룹만 적용되어 있을 뿐 별 다른 점은 없다. 그렇다면 구성이 다른걸까? 포함된 미들웨어의 목록도 벨의 것과 다르지 않다. 그런데 테러는 왜 미들웨어 그룹을 보면 이유를 알 수 있을거고 했을까?


누가쓰는 API인가


코드를 봐도 잘 이해를 못하는 나 같은 중생들을 위해 한 용자가 정답을 공유했다.

스크린샷 2019-07-08 오후 11.11.15.png



내 생각엔 테러가 인증때문에 그렇게 한 것 같다. API 우트에 붙은 api 미들웨어는 상태가 없어서(stateless) 인증을 위해 추가적인 코드가 필요하다. web 미들웨어는 이를 깔끔하게 처리한다.



추가적으로, api 우트와 web 우트를 어떻게 구분하느냐는 질문에 테러는 아래와 같이 대답했다.

스크린샷 2019-07-08 오후 11.12.15.png



반적으로 API 토큰을 이용해서 인증하는 건 api에 넣고, 세션을 이용해서 인증하는 건 web에 넣는다.



아하!


API 우트 파이 web.php와 api.php로 나뉜 이후로 매번 고민했던 내용이었다. AJAX로 데이터를 불러오는 API를 API인데 web.php에 넣어도 되나? 싶다가도 api.php에 넣자니 패스포트 설치하고 할 게 많은데 이렇게까지 해야하나? 싶었었다. 이제는 아주 명쾌한 기준을 갖게 됐다. 애플리케이션이 돌아가는 서버를 기준으로 나 자신이 쓰는 API는 web 미들웨어 그룹을, 그 이외에는 api 미들웨어 그룹을 쓰면된다. 조금 다르게 표현하자면 세션으로 로그인 유지가 되는 웹에서 호출할거면 그냥 web 우트에 쓰고, 세션으로 로그인을 유지할 수 없어서 토큰이 필요한 경우는 api 우트에 쓴다.



2019년 7월 8
1 1




유료 구독자 전용 레터입니다.

한 달 1만원으로 매일 라라벨 관련 메일 받아보시고 과거 메일도 열람하세요. 일반 구독으로 공개글만 받아보실 수도 있습니다.

구독하기 버튼을 눌러주시면 구독과 동시에 xly에도 가입됩니다.

이현석

바쁜 팀장님 대신 알려주는 신입 PHP 개발자 안내서를 쓰고, 클린 아키텍처 인 PHP를 번역했습니다. 2020년에 출간될 Laravel Up & Running 2nd Edition을 번역하고 있습니다.