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

无法向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);
    }
}
  • 写回答

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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 springboot 3.0 实现Security 6.x版本集成
  • ¥15 PHP-8.1 镜像无法用dockerfile里的CMD命令启动 只能进入容器启动,如何解决?(操作系统-ubuntu)
  • ¥15 请帮我解决一下下面六个代码
  • ¥15 关于资源监视工具的e-care有知道的嘛
  • ¥35 MIMO天线稀疏阵列排布问题
  • ¥60 用visual studio编写程序,利用间接平差求解水准网
  • ¥15 Llama如何调用shell或者Python
  • ¥20 谁能帮我挨个解读这个php语言编的代码什么意思?
  • ¥15 win10权限管理,限制普通用户使用删除功能
  • ¥15 minnio内存占用过大,内存没被回收(Windows环境)