ds211107
2018-10-10 08:57
浏览 219
已采纳

无法向Laravel端点发出HTTP请求

I'm having a really strange issue when trying to make a HTTP request in one of my tests. My api.php routes file looks like this:

$router->group(['prefix' => '/v1', 'middleware' => ['auth:api']], 
    function (\Illuminate\Routing\Router $router) {
        $router->apiResource('/contacts', 'ContactsController');

        $router->group(['prefix' => '/contacts'], 
            function (\Illuminate\Routing\Router $router) {
                $router->apiResource('/groups', 'Contacts\\GroupsController');
        });
});

Running php artisan route:list shows the following route as being registered

+------------+------------------------+--------------+------------------------------------------------------+----------------+
|   Method   |           URI          |      Name    |                        Action                        |   Middleware   |
+------------+------------------------+--------------+------------------------------------------------------+----------------+
| GET|HEAD   | api/v1/contacts/groups | groups.index | App\Http\Controllers\Contacts\GroupsController@index |  api auth:api  |
+------------+------------------------+--------------+------------------------------------------------------+----------------+

However when I run my test, I get a 404 response. The test is as follows:

public function testICanGetAllOfTheGroups()
{
    factory(Group::class)->times(3)->create();

    $this->json('GET', '/api/v1/contacts/groups')
            ->assertStatus(200)->assertJsonCount(3);
}

I have also tried running php artisan route:clear and php artisan cache:clear but it hasn't made a difference.

For authentication, I have created the following trait which I am using.

trait Authenticated
{
    /** @var \App\Models\User */
    protected $user;

    public function setUp()
    {
        parent::setUp();

        $this->user = factory(User::class)->create();
        Passport::actingAs($this->user);
    }
}

图片转代码服务由CSDN问答提供 功能建议

在我的一个测试中尝试发出HTTP请求时,我遇到了一个非常奇怪的问题。 我的 api.php 路由文件如下所示:

  $ router-> group(['prefix'=>'/ v1',  'middleware'=> ['auth:api']],
函数(\ Illuminate \ Routing \ Router $ router){
 $ router-> apiResource('/ contacts','ContactsController'); 
  
 $ router-> group(['prefix'=>'/ contacts'],
 function(\ Illuminate \ Routing \ Router $ router){
 $ router-> apiResource('/ groups',  'Contacts \\ GroupsController'); 
}); 
}); 
   
 
 

运行 php artisan route:list 显示 跟随路线注册

  + ------------ + -----------------  ------- + -------------- + ---------------------------  --------------------------- + ---------------- + \ N | 方法|  URI | 名称| 行动| 中间件| 
 + ------------ + ------------------------ + --------  ------ + -------------------------------------------  ----------- + ---------------- + \ N |  GET | HEAD |  api / v1 / contacts / groups |  groups.index |  App \ Http \ Controllers \ Contacts \ GroupsController @index |  api auth:api | 
 + ------------ + ------------------------ + -----  --------- + ----------------------------------------  -------------- ---------------- + + 
   
 
 

然而 当我运行测试时,我得到了404响应。 测试如下:

  public function testICanGetAllOfTheGroups()
 {
 factory(Group :: class) - > times(3) - > create()  ; 
 
 $ this-> json('GET','/ api / v1 / contacts / groups')
  - > assertStatus(200) - > assertJsonCount(3); 
} 
 <  / code>  
 
 

我也试过运行 php artisan route:clear php artisan cache:clear 但是还没有制作 差异。

对于身份验证,我创建了以下我正在使用的特征。

  trait Authenticated 
 {
 /  ** @var \ App \ Models \ User * / 
 protected $ user; 
 
 public function setUp()
 {
 parent :: setUp(); 
 
 $ this-&gt; user =  factory(User :: class) - &gt; create(); 
 Passport :: actingAs($ this-&gt; user); 
} 
} 
   
 
  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

3条回答 默认 最新

  • dsxrq28228 2018-10-10 09:12
    已采纳

    I appear to have figured this out. If I re-arrange the routes from

    $router->group(['prefix' => '/v1', 'middleware' => ['auth:api']], function (\Illuminate\Routing\Router $router) {
        $router->apiResource('/contacts', 'ContactsController');
    
        $router->group(['prefix' => '/contacts'], function (\Illuminate\Routing\Router $router) {
            $router->apiResource('/groups', 'Contacts\\GroupsController');
        });
    });
    

    to

    $router->group(['prefix' => '/v1', 'middleware' => ['auth:api']], function (\Illuminate\Routing\Router $router) {
        $router->group(['prefix' => '/contacts'], function (\Illuminate\Routing\Router $router) {
            $router->apiResource('/groups', 'Contacts\\GroupsController');
        });
    
        $router->apiResource('/contacts', 'ContactsController');
    });
    

    It then works. I suspect this is a bug with how Laravel is registering it's routes as POST and PUT requests still work fine.

    I have raised this as a bug on GitHub - https://github.com/laravel/framework/issues/26038


    UPDATE

    I have now identified the issue. Basically the apiResource translates one of the endpoints to:

    /contacts/{contact}.

    Following on from that one of the routes is contacts/groups. However in order for Laravel to match it with contacts/groups it needs to be before /contacts/{contact} as it is a wildcard. Whether or not it is intentional behaviour I'm not sure, but at the moment just having the routes the other way around fixes this.

    点赞 打赏 评论
  • doulao7572 2018-10-10 09:09

    This is an authenticated route. To get access to this route in a test you need to use the

    $this->actingAs(User $user); 
    

    Method.

    Reference: Laravel Docs

    Your code should work like the following:

    public function testICanGetAllOfTheGroups()
    {
        factory(Group::class)->times(3)->create();
        $user = factory(User::class)->create();  // Create user for authentication
        this->actingAs($user)                  // Pass user to the request
            ->json('GET', '/api/v1/contacts/groups')->assertStatus(200)->assertJsonCount(3);
    }
    

    I hope this helps you out.

    点赞 打赏 评论
  • dongzhanjuan5141 2018-10-10 09:20

    why dont you put both routes in the contacts group ?

    $router->group(['prefix' => '/v1', 'middleware' => ['auth:api']], function (\Illuminate\Routing\Router $router) {
        $router->group(['prefix' => '/contacts'], function (\Illuminate\Routing\Router $router) {
            $router->apiResource('/', 'ContactsController');
            $router->apiResource('/groups', 'Contacts\\GroupsController');
        });
    });
    
    点赞 打赏 评论

相关推荐 更多相似问题