Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can i run SPA and gateway in one project #606

Closed
pessimca opened this issue Sep 7, 2018 · 7 comments
Closed

Can i run SPA and gateway in one project #606

pessimca opened this issue Sep 7, 2018 · 7 comments
Labels
question Initially seen a question could become a new feature or bug or closed ;)

Comments

@pessimca
Copy link

pessimca commented Sep 7, 2018

I am new to Ocelot and just started exploring it. I have a SPA (.NET Core Angular) and I have call multiple API's. We were asked to use .NET Core controller to call API's using HttpClient. Found your source as great help to overcome duplicating controllers. But could not able to run SPA and gateway using one project.

Do we have any options to do it? Please let me know.

Below is the my configuration:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SpaServices.AngularCli;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Ocelot.DependencyInjection;
using Ocelot.Middleware;

namespace _04_myAngularApp
{
    public class Startup
    {
        public Startup(IHostingEnvironment env)
        {
            var builder = new ConfigurationBuilder()
                .SetBasePath(env.ContentRootPath)
                .AddJsonFile("appsettings.json", optional: true, reloadOnChange: true)
                .AddJsonFile($"appsettings.{env.EnvironmentName}.json", optional: true)
                //.AddJsonFile("ocelot.json")
                .AddEnvironmentVariables();

            Configuration = builder.Build();
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddOcelot(Configuration);
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);

            // In production, the Angular files will be served from this directory
            services.AddSpaStaticFiles(configuration =>
            {
                configuration.RootPath = "ClientApp/dist";
            });
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }
            
            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseSpaStaticFiles();

            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller}/{action=Index}/{id?}");
            });

            app.UseSpa(spa =>
            {
                // To learn more about options for serving an Angular SPA from ASP.NET Core,
                // see https://go.microsoft.com/fwlink/?linkid=864501

                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseAngularCliServer(npmScript: "start");
                }
            });

            app.UseOcelot().Wait();
        }
    }
}

Please let me know if it is possible.

Thank you.

@TomPallister
Copy link
Member

@pessimca I am not aware of anyone using Ocelot for this purpose and it is not a scenario we "support" however you might be able to do it using Map middleware. If you wrap app.UseOcelot.Wait() in a Map middleware say on the path "/ocelot-routes" then asp.net will send any calls to /ocelot-routes to the Ocelot middleware. You can read more about this here. Let me know if you get it working. I would be interested :)

@TomPallister TomPallister added the question Initially seen a question could become a new feature or bug or closed ;) label Sep 8, 2018
@pessimca
Copy link
Author

pessimca commented Sep 10, 2018

I am able to make by adding below code:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseSpaStaticFiles();

            app.Map("/mvc", HandleMapMvc);
            app.Map("/api", HandleMapApiGateway);
            app.UseSpa(spa =>
            {
                // To learn more about options for serving an Angular SPA from ASP.NET Core,
                // see https://go.microsoft.com/fwlink/?linkid=864501

                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseAngularCliServer(npmScript: "start");
                }
            });
        }

        private static void HandleMapApiGateway(IApplicationBuilder app)
        {
            app.UseOcelot().Wait();
        }

        private static void HandleMapMvc(IApplicationBuilder app)
        {
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller}/{action=Index}/{id?}");
            });
        }

Thank you.

@Kevin-Deason
Copy link

My suggestion, and what we have done, is to create separate projects for everything and use ocelot routes to redirect to the frontend page.

You can use a catch all route for this.

See: https://ocelot.readthedocs.io/en/latest/features/routing.html

All our services/apps are hosted with local urls and are not public facing. Only public facing site is the gateway.

Your above suggested solution goes against Gateway pattern and microservices.

@TomPallister
Copy link
Member

@pessimca interesting! I never thought anyone would use Ocelot like this!

I think @Kevin-Deason advice is pretty good :)

I will close this for now :)

@tonymathewt
Copy link

@TomPallister Is there a way we could skip the UseOcelot() call in Startup's Configure() and we can explicitly specify in the Action/Controller (or anywhere else) when manually invoking another API call that it should go through Ocelot?
Intention is, don't want to modify the existing pipeline of SPA

@fadem
Copy link

fadem commented Feb 27, 2020

hi, I have a question about the request to aggregates from Angular CLI.
I set the configuration that I needed for "Aggregates". Normally this Route work on the requested URL but when I try to this on Angular CLI it was returned response "Cors Origin Error". I set the configuration for "Cors Origin Error" and those are work one by one without returned response "Cors Origin Error".

@gkumar1234
Copy link

I am able to make by adding below code:

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseExceptionHandler("/Error");
                app.UseHsts();
            }

            app.UseHttpsRedirection();
            app.UseStaticFiles();
            app.UseSpaStaticFiles();

            app.Map("/mvc", HandleMapMvc);
            app.Map("/api", HandleMapApiGateway);
            app.UseSpa(spa =>
            {
                // To learn more about options for serving an Angular SPA from ASP.NET Core,
                // see https://go.microsoft.com/fwlink/?linkid=864501

                spa.Options.SourcePath = "ClientApp";

                if (env.IsDevelopment())
                {
                    spa.UseAngularCliServer(npmScript: "start");
                }
            });
        }

        private static void HandleMapApiGateway(IApplicationBuilder app)
        {
            app.UseOcelot().Wait();
        }

        private static void HandleMapMvc(IApplicationBuilder app)
        {
            app.UseMvc(routes =>
            {
                routes.MapRoute(
                    name: "default",
                    template: "{controller}/{action=Index}/{id?}");
            });
        }

Thank you.

Not sure what i am missing, this did not help. Always Gateway requests are giving 404 error.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
question Initially seen a question could become a new feature or bug or closed ;)
Projects
None yet
Development

No branches or pull requests

6 participants