diff --git a/lib/Mojolicious/Plugin/Yancy.pm b/lib/Mojolicious/Plugin/Yancy.pm index df3bffb3..26b0b912 100644 --- a/lib/Mojolicious/Plugin/Yancy.pm +++ b/lib/Mojolicious/Plugin/Yancy.pm @@ -369,7 +369,9 @@ has _filters => sub { {} }; sub register { my ( $self, $app, $config ) = @_; - my $route = $config->{route} // $app->routes->any( $config->{yancy_path} // '/yancy' ); + my $yancy_path = $config->{yancy_path} // '/yancy'; + my $route = $config->{route} // $app->routes->any( $yancy_path ); + my $api_path = $config->{api_path} // $yancy_path . '/api'; $route->to( return_to => $config->{return_to} // '/' ); $config->{api_controller} //= 'Yancy::API'; @@ -434,7 +436,7 @@ sub register { # Add OpenAPI spec my $openapi = $app->plugin( OpenAPI => { - route => $route->any( '/api' )->name( 'yancy.api' ), + route => $route->parent->any( $api_path )->name( 'yancy.api' ), spec => $self->_build_openapi_spec( $config ), } ); $app->helper( 'yancy.openapi' => sub { $openapi } ); diff --git a/lib/Yancy/Help/Config.pod b/lib/Yancy/Help/Config.pod index d1e699ff..73088302 100644 --- a/lib/Yancy/Help/Config.pod +++ b/lib/Yancy/Help/Config.pod @@ -435,6 +435,11 @@ To customize the URL under which the Yancy editor is found. If not given, defaults to C. Note, the various assets will still live on the web app under C. +=head2 C + +To customize the URL under which the Yancy API is found. If not given, +defaults to C under the C value. + =head1 SEE ALSO L, L diff --git a/t/api.t b/t/api.t index 378071aa..9008699f 100644 --- a/t/api.t +++ b/t/api.t @@ -126,7 +126,8 @@ subtest 'declared collections' => \&test_api, Test::Mojo->new( 'Yancy', { backend => $backend_url, collections => $collections, - } ); + } ), + '/yancy/api'; ( $backend_url, $backend, %items ) = init_backend( $collections, %data ); subtest 'read_schema collections' => \&test_api, @@ -134,7 +135,17 @@ subtest 'read_schema collections' => \&test_api, backend => $backend_url, collections => $collections, read_schema => 1, - } ); + } ), + '/yancy/api'; + +( $backend_url, $backend, %items ) = init_backend( $collections, %data ); +subtest 'different API URL' => \&test_api, + Test::Mojo->new( 'Yancy', { + backend => $backend_url, + collections => $collections, + api_path => '/api', + } ), + '/api'; subtest 'schema completely from database' => sub { my $t = Test::Mojo->new( Yancy => { @@ -225,10 +236,10 @@ subtest 'x-ignore' => sub { done_testing; sub test_api { - my ( $t ) = @_; + my ( $t, $api_path ) = @_; subtest 'fetch generated OpenAPI spec' => sub { - $t->get_ok( '/yancy/api' ) + $t->get_ok( $api_path ) ->status_is( 200 ) ->content_type_like( qr{^application/json} ) ->json_is( '/definitions/people' => { @@ -322,7 +333,7 @@ sub test_api { }; subtest 'fetch list' => sub { - $t->get_ok( '/yancy/api/people' ) + $t->get_ok( $api_path . '/people' ) ->status_is( 200 ) ->json_is( { items => [ @@ -350,7 +361,7 @@ sub test_api { } ); subtest 'limit/offset' => sub { - $t->get_ok( '/yancy/api/people?$limit=1' ) + $t->get_ok( $api_path . '/people?$limit=1' ) ->status_is( 200 ) ->json_is( { items => [ @@ -365,7 +376,7 @@ sub test_api { total => 3, } ); - $t->get_ok( '/yancy/api/people?$offset=1' ) + $t->get_ok( $api_path . '/people?$offset=1' ) ->status_is( 200 ) ->json_is( { items => [ @@ -389,7 +400,7 @@ sub test_api { subtest 'order_by' => sub { - $t->get_ok( '/yancy/api/people?$order_by=asc:name' ) + $t->get_ok( $api_path . '/people?$order_by=asc:name' ) ->status_is( 200 ) ->json_is( { items => [ @@ -416,7 +427,7 @@ sub test_api { total => 3, } ); - $t->get_ok( '/yancy/api/people?$order_by=desc:name' ) + $t->get_ok( $api_path . '/people?$order_by=desc:name' ) ->status_is( 200 ) ->json_is( { items => [ @@ -446,7 +457,7 @@ sub test_api { }; subtest 'filter' => sub { - $t->get_ok( '/yancy/api/people?name=Doug*' ) + $t->get_ok( $api_path . '/people?name=Doug*' ) ->status_is( 200 ) ->json_is( { items => [ @@ -461,7 +472,7 @@ sub test_api { total => 1, } ); - $t->get_ok( '/yancy/api/people?name=*l' ) + $t->get_ok( $api_path . '/people?name=*l' ) ->status_is( 200 ) ->json_is( { items => [ @@ -476,7 +487,7 @@ sub test_api { total => 1, } ); - $t->get_ok( '/yancy/api/people?name=er' ) + $t->get_ok( $api_path . '/people?name=er' ) ->status_is( 200 ) ->json_is( { items => [ @@ -501,7 +512,7 @@ sub test_api { }; subtest 'fetch one' => sub { - $t->get_ok( '/yancy/api/people/' . $items{people}[0]{id} ) + $t->get_ok( $api_path . '/people/' . $items{people}[0]{id} ) ->status_is( 200 ) ->json_is( { @@ -512,7 +523,7 @@ sub test_api { contact => 1, }, ); - $t->get_ok( '/yancy/api/people/' . $items{people}[2]{id} ) + $t->get_ok( $api_path . '/people/' . $items{people}[2]{id} ) ->status_is( 200 ) ->json_is( { @@ -521,7 +532,7 @@ sub test_api { contact => 0, }, ); - $t->get_ok( '/yancy/api/user/doug' ) + $t->get_ok( $api_path . '/user/doug' ) ->status_is( 200 ) ->json_is( { @@ -543,7 +554,7 @@ sub test_api { age => 35, contact => 1, }; - $t->put_ok( '/yancy/api/people/' . $items{people}[0]{id} => json => $new_person ) + $t->put_ok( $api_path . '/people/' . $items{people}[0]{id} => json => $new_person ) ->status_is( 200 ) ->json_is( $new_person ); is_deeply $backend->get( people => $items{people}[0]{id} ), $new_person; @@ -555,7 +566,7 @@ sub test_api { access => 'user', age => 35, }; - $t->put_ok( '/yancy/api/user/doug' => json => $new_user ) + $t->put_ok( $api_path . '/user/doug' => json => $new_user ) ->status_is( 200 ); $t->json_is( { %$new_user, id => $items{user}[0]{id} } ); is_deeply $backend->get( user => 'doug' ), @@ -570,7 +581,7 @@ sub test_api { age => 3, contact => 0, }; - $t->post_ok( '/yancy/api/people' => json => $new_person ) + $t->post_ok( $api_path . '/people' => json => $new_person ) ->status_is( 201 ) ->json_is( $new_person->{id} ) ; @@ -582,7 +593,7 @@ sub test_api { password => 'ignore', access => 'user', }; - $t->post_ok( '/yancy/api/user' => json => $new_user ) + $t->post_ok( $api_path . '/user' => json => $new_user ) ->status_is( 201 ) ->json_is( 'flexo' ); my $got = $backend->get( user => 'flexo' ); @@ -594,12 +605,12 @@ sub test_api { }; subtest 'delete one' => sub { - $t->delete_ok( '/yancy/api/people/4' ) + $t->delete_ok( $api_path . '/people/4' ) ->status_is( 204 ) ; ok !$backend->get( people => 4 ), 'person 4 not exists'; - $t->delete_ok( '/yancy/api/user/flexo' ) + $t->delete_ok( $api_path . '/user/flexo' ) ->status_is( 204 ) ; ok !$backend->get( user => 'flexo' ), 'flexo not exists';