질문을 삭제하지 말아주세요.!
 
1
0
-1

현재 실전PHP 웹프로그래밍 책을 보면서 조금 변형을 해보았습니다.

기본적으로 리소스 컨트롤러에 다른 method(Route:put)을 추가하는 것은  작동을 합니다.
상단에 있는 것을 먼저 실행 하는게 맞죠? 

Route::put('articles/{id}', 'ArticlesController@overrideUpdate');
Route::resource('articles', 'ArticlesController');
Route::any('articles', function() {
    return 'any';
});


문제는 리소스 컨트롤러에서 라우팅 되지 못한 URL를 처리하려고 any 메소드를 추가했더니 전부 any 메소드를 타고 넘어가네요.

php artisan route:list 는 혹시 우선 순위로 리스팅되는 건가요?

--------+--------------------------------+-------------------------+------------------+--------------------------------------------------------+--------------+
| Domain | Method                         | URI                     | Name             | Action                                                 | Middleware   |
+--------+--------------------------------+-------------------------+------------------+--------------------------------------------------------+--------------+
|        | GET|HEAD                       | /                       |                  | Closure                                                | web          |
|        | GET|HEAD                       | api/user                |                  | Closure                                                | api,auth:api |
|        | GET|HEAD                       | articles                | articles.index   | App\Http\Controllers\ArticlesController@index          | web          |
|        | POST                           | articles                | articles.store   | App\Http\Controllers\ArticlesController@store          | web          |
|        | GET|HEAD|POST|PUT|PATCH|DELETE | articles                |                  | Closure                                                | 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          |
|        | GET|HEAD                       | articles/{article}/edit | articles.edit    | App\Http\Controllers\ArticlesController@edit           | web          |
|        | PUT                            | articles/{id}           |                  | App\Http\Controllers\ArticlesController@overrideUpdate | web          |
+--------+--------------------------------+-------------------------+------------------+--------------------------------------------------------+--------------+


  1. 김주원

    아 맞습니다. 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를 실제로 막뒤썩은 후에 정렬해 보면 딱 저렇게 나올 것 같아요.

  2. 김윤수

    넵, 답변 감사합니다.

    Route가 익히기에는 쉬운데, 실제 서비스에 적용하다 보면 생각보다 변수가 어렵더구요. 
    설계를 잘 해놓고 덤버야 될 것 같습니다. 

CommentAdd your comment...

4 answers

  1.  
    1
    0
    -1

    같은 라우팅이라면 나중에 정의된 라우트가 먼저 정의된 라우트를 오버라이드합니다.

    Route::any를 Route::resource 위로 옮기고, $id  라우트 파라미터를 패턴으로 정확하게 정의해 주면 ANY /articles/foo 와 같이 정의되지 않은 라우트는 Route::any를 타지 않을까 싶습니다. 한 번 실험해 보시고, 안되면 다시 한 번 질문해 주세요.

      CommentAdd your comment...
    1.  
      1
      0
      -1

      문제점을 찾았습니다.
      라우트 파라미터 명이 문제 였네요. 
      라우트 파라미터 명을 {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          |
      +--------+--------------------------------+-------------------------+------------------+--------------------------------------------------------+--------------+
        CommentAdd your comment...
      1.  
        1
        0
        -1

        나중에 정의된 라우트가 먼저 정의된 라우트를 오버라이드 하면

        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 오버라이드가 이루집니다.

          CommentAdd your comment...
        1.  
          1
          0
          -1

          앗 그리고, $ php artisan route:list 했을 때 정렬 순서는 기본 값이 Url 오름 차순입니다. $ php artisan help route:list를 해 보시면 정렬 및 필터링에 관한 몇 가지 옵션을 확인할 수 있습니다. 코드로 보고 싶다면 다음 링크를 참고해 주세요.


          https://github.com/laravel/framework/blob/5.3/src/Illuminate/Foundation/Console/RouteListCommand.php#L91-L99

            CommentAdd your comment...