How to set api route separate to website in self hosted app

I’ve downloaded a servicestack example from the get started page : like this.

When running I’d like the website to run under the normal url, such as https://localhost:4200, and the api to run under https://localhost:4200/api.

When I set HandlerFactoryPath("/api") in the HostConfig it causes the app to serve the api under the correct url but the website no longer loads from the original url.

What am I doing wrong? Or, not doing…?

Try changing or disabling the built-in API route:
https://docs.servicestack.net/routing#disable-api-route

Thanks; I’ve tried disabling the built in api route. Its the website that stops functioning though.

I can reach the api ui at https://localhost:4200/api/ui and reach endpoints like https://localhost:4200/api/license

But the website returns A 404…
image

I can find index.html at https://localhost/api but I get 404s on the css and js it attempts to load.

Its as if setting HandlerFactoryPath on the HostConfig has changed the website root to /api as well. And the other resources aren’t available there. I’d like the website to be accessible from /

You would use PathBase to configure a base path in .NET Core Apps:

https://docs.servicestack.net/netcore#hosting-asp-net-core-apps-on-custom-path

app.UseServiceStack(new AppHost {
    PathBase = "/api",
    AppSettings = new NetCoreAppSettings(Configuration)
});

This would host all of ServiceStack on the configured PathBase if you just want ServiceStack APIs on /api you would instead prefix your routes with it, i.e:

[Route("/api/acme")]
1 Like

The PathBase method result is the same - the angular site stops working.

The Route Attribute is an option but how do I override the route on the authenticate endpoints?

Nevermind - I’ve found the ServerRoutes property on the AuthFeature.

Its a shame this can’t be done easily without breaking your starter apps websites; I’d much prefer this option

Since ServiceStack is hosting everything, including static files here (your Angular app), yes the PathBase change includes the deployed Angular site.

The angular-spa template is designed for the API + Angular site to be hosted together where the API base path is at the same location as the Angular app.

I get the preference, the starter templates are geared for least moving parts, and hosting everything together from the same base path is easier than drawing a line within the one host. A common pattern for a clean separation of API and client application (and something I’ve done many times) is to host them separately. This avoid any unusual configuration of plugins, base paths etc.

For example, you could use a static host like AWS S3 for your deployed Angular app, and ServiceStack APIs are hosted else where, managing the /api separation in AWS CloudFront or Nginx rule etc. Locally you can use a proxy or just have the base path on the Angular client change on deployment.

In the long run I think this will result in less headaches. Hope that helps.

1 Like

Cheers @layoric (same surname as me btw :smile:). I totally understand and thanks for the explanation.

We’re actually moving from the configuration you described with our .net 4 servicestack services, changing them to .net core. I’m not familiar with the .net core nuances so I thought I’d cut corners by using the starter apps. I actually like how the api + angular are served together. It helps with config on our customers’ on premise infrastructure.

I’ve changed the route attributes in the meantime and will see what other issues I find before deciding to separate the api and website from one another.

1 Like

One thing I’ll add that with the new JSON /api pre-defined route all APIs by default (i.e. if you don’t disable it) can be called from the /api/{Request} path, e.g. Authenticating would call /api/Authenticate instead of /auth.

You can configure your Angular SPA client to use the pre-defined /api route with:

export const client = new JsonServiceClient(API_URL).apply(c => {
    c.basePath = "/api"
    c.headers = new Headers() //avoid pre-flight CORS requests
})
1 Like