같은 라우팅이라면 나중에 정의된 라우트가 먼저 정의된 라우트를 오버라이드합니다.
Route::any를 Route::resource 위로 옮기고, $id 라우트 파라미터를 패턴으로 정확하게 정의해 주면 ANY /articles/foo 와 같이 정의되지 않은 라우트는 Route::any를 타지 않을까 싶습니다. 한 번 실험해 보시고, 안되면 다시 한 번 질문해 주세요.
문제점을 찾았습니다.
라우트 파라미터 명이 문제 였네요.
라우트 파라미터 명을 {aricle}로 바꾸니 의도된 작동을 합니다.
Route::resource('articles', 'ArticlesController'); Route::put('articles/{id}', 'ArticlesController@overrideUpdate');
Route::resource('articles', 'ArticlesController'); Route::put('articles/{article}', 'ArticlesController@overrideUpdate');
파라미터 명이 왜 문제였는지 이해가 안되네요.
또, route:list 예서 edit 메소드가 맨 뒤에 정의 된것도 이해가 안갑니다. ㅠㅜ
+--------+--------------------------------+-------------------------+------------------+--------------------------------------------------------+--------------+ | Domain | Method | URI | Name | Action | Middleware | +--------+--------------------------------+-------------------------+------------------+--------------------------------------------------------+--------------+ | | GET|HEAD | / | | Closure | web | | | GET|HEAD | api/user | | Closure | api,auth:api | | | GET|HEAD|POST|PUT|PATCH|DELETE | articles | | Closure | web | | | GET|HEAD | articles | articles.index | App\Http\Controllers\ArticlesController@index | web | | | POST | articles | articles.store | App\Http\Controllers\ArticlesController@store | web | | | GET|HEAD | articles/create | articles.create | App\Http\Controllers\ArticlesController@create | web | | | GET|HEAD | articles/{article} | articles.show | App\Http\Controllers\ArticlesController@show | web | | | PUT|PATCH | articles/{article} | articles.update | App\Http\Controllers\ArticlesController@update | web | | | DELETE | articles/{article} | articles.destroy | App\Http\Controllers\ArticlesController@destroy | web | | | PUT | articles/{article} | | App\Http\Controllers\ArticlesController@overrideUpdate | web | | | GET|HEAD | articles/{article}/edit | articles.edit | App\Http\Controllers\ArticlesController@edit | web | +--------+--------------------------------+-------------------------+------------------+--------------------------------------------------------+--------------+
나중에 정의된 라우트가 먼저 정의된 라우트를 오버라이드 하면
Route::any('articles', function() { return 'any'; }); Route::resource('articles', 'ArticlesController'); Route::put('articles/{id}', 'ArticlesController@overrideUpdate');
이렇게 해야하는게 맞는데, 실제 postman으로 테스트해보면
Route::any('articles', function() { return 'any'; }); Route::put('articles/{id}', 'ArticlesController@overrideUpdate'); Route::resource('articles', 'ArticlesController');
이렇게 해야 의도된 PUT Method 오버라이드가 이루집니다.
앗 그리고, $ php artisan route:list 했을 때 정렬 순서는 기본 값이 Url 오름 차순입니다. $ php artisan help route:list를 해 보시면 정렬 및 필터링에 관한 몇 가지 옵션을 확인할 수 있습니다. 코드로 보고 싶다면 다음 링크를 참고해 주세요.
현재 실전PHP 웹프로그래밍 책을 보면서 조금 변형을 해보았습니다.
기본적으로 리소스 컨트롤러에 다른 method(Route:put)을 추가하는 것은 작동을 합니다.
상단에 있는 것을 먼저 실행 하는게 맞죠?
문제는 리소스 컨트롤러에서 라우팅 되지 못한 URL를 처리하려고 any 메소드를 추가했더니 전부 any 메소드를 타고 넘어가네요.
php artisan route:list 는 혹시 우선 순위로 리스팅되는 건가요?
아 맞습니다. RESTful Resource Route는 라우트 파라미터를 Url을 단수화해서 사용합니다. id가 아니라 article이 맞습니다. Route::resource() 메서드의 세번째 인자에 parameters 배열키로 라우트 파라미터를 명시적으로 지정해 주지 않으면 저게 컨벤션입니다.
https://github.com/laravel/framework/blob/5.3/src/Illuminate/Routing/ResourceRegistrar.php#L75-L77
그리고 route:list로 출력된 URI를 실제로 막뒤썩은 후에 정렬해 보면 딱 저렇게 나올 것 같아요.
넵, 답변 감사합니다.
Route가 익히기에는 쉬운데, 실제 서비스에 적용하다 보면 생각보다 변수가 어렵더구요.
설계를 잘 해놓고 덤버야 될 것 같습니다.