Symfony 4.2 and Nelmio Api Doc Bundle - Several documentation with multiple Controllers - api

I'm using Symfony 4 and Nelmio Api Doc Bundle to create a service that will be only accessible trough APIs (both public frontend and private back office will be created using a JS framework)
I need 2 documentations (maybe more later) :
/api/doc
/admin/doc
Right now I have some Controllers in src/Controllers/Admin and src/Controller/API since they are really different.
I don't understand how to use Nelmio Api Doc Bundle to handle the 2 documentations in 2 differents urls. I know there are areas but I just don't get how to deal with them...
Can someone help me by providing a simple example ?
Thanks

As you mention you need to configure the areas section of the nelmio_api_doc.yaml file as listed here https://symfony.com/doc/current/bundles/NelmioApiDocBundle/areas.html
In your case you would have the package nelmio_api_doc.yaml file as something like:
nelmio_api_doc:
areas:
default:
path_patterns: [ ^/api ]
admin:
path_patterns: [ ^/admin ]
Or whatever the patterns in your routes are to these so it knows which controller function(s) to check for the swagger annotations.
And in your routing config nelmio_api_doc.yaml:
app.swagger_ui:
path: /doc/{area}
methods: GET
defaults: { _controller: nelmio_api_doc.controller.swagger_ui, area: api }
So the api documentation will be accessible via /doc or /doc/api, any other areas can be accessed by adding appending the area name for example /doc/admin etc.
Note that I have set the route as /doc/ to prevent a conflict with the firewall pattern set for ^/api picking it up first as it may conflict, you could add an extra firewall rule to catch it first, I decided to just change the route for this.
If you went with the swagger ui route as /api/doc you would need to change the default area path patterns to:
path_patterns: [ ^/api(?!/doc$) ]
As show in the symfony docs.

Related

How would I make Vue Router work with GitHub Pages?

I just deployed my Vue app to my website using GitHub Pages.
The website is successfully hosted at https://astroorbis.com.
Here's the problem; When you click the "links" button at the top of the page, it successfully nagivates you to https://astroorbis.com/links, but when you try visiting the URL itself (typing in https://astroorbis.com/links) into your browser, it returns a 404.
There are other links that have the same error, such as /discord, /github, etc.
I tried the solution at Vue Router, GitHub Pages, and Custom Domain Not Working With Routed Links, but it failed as well.
What would be the solution for this?
As stated in this section of the HTML5 mode
Here comes a problem, though: Since our app is a single page client side app, without a proper server configuration, the users will get a 404 error if they access https://example.com/user/id directly in their browser. Now that's ugly.
Not to worry: To fix the issue, all you need to do is add a simple catch-all fallback route to your server. If the URL doesn't match any static assets, it should serve the same index.html page that your app lives in. Beautiful, again!
So, the solution would be to use something like that
const routes = [
// will match everything and put it under `$route.params.pathMatch`
{ path: '/:pathMatch(.*)*', name: 'NotFound', component: NotFound },
]
On Netlify, you also need to add the following for it to work
/public/_redirects
/* /index.html 200
So I'm not sure about Github Pages but you should have something similar there, some way of catching all routes and sending them to the index.html of your initial SPA page load.
Otherwise maybe just give a try to Netlify with the _redirects configuration.
Maybe this article could help regarding Github pages.
The hack in your given link seems to be the only viable solution but it's still bad for SEO so yeah, depends if you want any (I guess so).
In that case, you could try Nuxt.js, Gridsome or Vitesse if you want to have some statically generated pages (best approach regarding SEO).

Can you prefix internal ABP routes?

I am using ABP v3.3 on ASP.NET Core 3.1 in a microservice environment.
We are wanting to prefix our microservice routes with the service name.
E.g, accounting service would be:
/accounting/api/invoices
/accounting/api/payments
This is fine with our own controllers as we can define the route with route attributes. E.g [Route("accounting/api/invoices")]
However for internal abp routes like
/api/abp/api-definition
where the controller is defined in the Abp module with these route attributes already applied, how do we go about adding this prefix?
I can’t find anywhere in the documentation anything relating to this, except for the case of conventional controller creation which is not applicable here.
The above is to support the scenario where all microservices are behind an internal load balancer, and all /accounting routes should forward to this single service. This is troublesome currently when using IHttpClientProxy for service-to-service requests, as the /api/abp/api-definition request needs to be forwarded to the specific microservice.
The only alternative approach I have found is to set root paths for all services as http://<loadbalancer>/<servicename>, and then in each service add the line
app.UsePathBase("/accounting")
which strips the above path from the requests to enable route matching.
This however does cause additional issues with the generated Swagger docs from showing this additional route path, which can become confusing.
Any help appreciated
yes but not recommended because you need to replace several code parts.
for example
https://github.com/abpframework/abp/blob/dev/framework/src/Volo.Abp.Http.Client/Volo/Abp/Http/Client/DynamicProxying/ApiDescriptionFinder.cs#L94
https://github.com/abpframework/abp-samples/blob/master/MicroserviceDemo/gateways/BackendAdminAppGateway.Host/BackendAdminAppGatewayHostModule.cs#L126
https://github.com/abpframework/abp/blob/dev/modules/blogging/src/Volo.Blogging.HttpApi/Volo/Blogging/BlogsController.cs#L14

How to change base url?

I am not sure the title of the question is correct, but I'll try to explain what I need.
We host multiple web applications on a single machine, so
https://localhost:8080
and
https://localhost:8081
point to different applications.
Meanwhile, API gateway maps request without dropping the URL suffix:
https://api.domain.com/service1/Home/Index
turns into
https://localhost:8080/service1/Home/Index
and
https://api.domain.com/service2/Home/Index
into
https://localhost:8081/service2/Home/Index
I would like the app's root ~ to resolve to hostUrl+suffix where suffix is a configured value.
I used this blogpost to globally prefix all the routes for controllers and pages, but now I struggle with static files.
I am able to virtually move wwwroot:
app.UseStaticFiles(new StaticFileOptions
{
RequestPath = $"/{GlobalPrefix}"
});
but <link href="~/bootstrap/css/bootstrap.css" rel="stylesheet" /> does not contain GlobalPrefix part when rendered.
So I would like to add this GlobalPrefix to whatever base URL site is hosted at. Be it a self-hosted app or in IIS.
P.S. RTFM =)
Using app.UsePathBase("/myPath")(https://learn.microsoft.com/en-us/dotnet/api/microsoft.aspnetcore.builder.usepathbaseextensions.usepathbase?view=aspnetcore-2.2) is working in that case.
There have been changes in ASP.NET Core 2 regarding that (http://github.com/aspnet/Announcements/issues/226). Also, be aware of a strange behavior: http://github.com/aspnet/HttpAbstractions/issues/893

API versioning in Symfony

I've been trying to find a solution to versioning in Symfony.
What would be the best way to do API versioning in Symfony. In Laravel this is pretty simple, see here
You just separate everything in different folders like V1/V2... and you create routes that points to that folder (namespace). But Symfony works differently, it uses annotation to create routes
Symfony also provide easy way to version your code.
So if you want to separate your controllers in different folders like v1,v2 etc. then you can when import routes add prefix for each folder.
So in config/routes/annotations.yaml or app/config/routing.yml file you can define:
v1_controllers:
resource: ../../src/Controller/v1 # add correct path
type: annotation
prefix: '/v1'
v2_controllers:
resource: ../../src/Controller/v2 # add correct path
type: annotation
prefix: '/v2'
So after this all routes in v1 folder will have prefix v1.
Please check symfony routing.

How to remove the context path when viewing authenticated content

I'm working on a grails application that sits on a server with another root.war application. Currently we use apache redirects to hide the context path (name of our grails application) as we already have a root.war and we don't want it to show on all our urls. This works for our public content. However, now that we've added some authenticated content with spring security core plugin it always redirects to include the context path. Hence, the url /authcontent/page.gsp is getting redirected to /appname/authcontent/page.gsp. Some folks have mentioned you can remove the context path by creating a separate virtual host in tomcat, but I was wondering if there's a way to override the mechanism that Spring Security uses to do the redirect in the filter chain. Perhaps overriding the RequestCacheAwareFilter? but I believe that filter only is used after the initial authentication. I've read through the spring security documentation but it doesn't talk as much about redirecting requests as much as the whole authentication and authorization process so I'm wondering if this is in the plugin itself. Any thoughts would be helpful.
You can remove the app context in the Config.groovy file:
environments {
development {
grails.logging.jul.usebridge = true
grails.serverURL = "http://localhost:8080"
grails.app.context = "/"
}
production {
grails.logging.jul.usebridge = false
grails.serverURL = "http://yourwebsite.com"
grails.app.context = "/"
}
}
Hope that helps.
There's number of ways of doing this. Two I tried were overriding the requestCache bean (but then you also had to override the DefaultSavedRequest) and overriding the redirectStategy bean which is what I'm using as it was simpler.