What is a good architecture to add an API to an existing ASP.Net Core 2.2 MVC solution

137 views Asked by At

When I started development of my current project I had no knowledge or prior experience of web development, ASP.Net (Core), C#, JS and so on. With a lot of reading, excercising and testing I now have an ASP.Net Core 2.2 web application with multi-tenancy based on the database-per-tenant strategy hosted on Azure with Azure SQL as backend. I have a solution with 2 projects:

  • the MVC web application that also has the .Net Core Identity from which I use the individual user accounts stored in ASPNet... tables (I did implement my custom UI, mainly so I could use the Localization middleware already used throughout the application)
  • a data layer that contains the db context's, the data models and the repository

Now I need at add an API. The sole purpose of the API is cleary defined: give customers(tenants) the possibility to import and export data, most likely connected to other customer's application(s). This API will not be used by the UI. The API will not be hit with thousands of queries per second. It will be part of a business solution with 50 to 200 customers who will perform occassional import/export actions. I have already implemented Identity and the authentication for the API should be done against the users setup in Identity but with a different authentication mechanism.

I have done a fair bit of searching and reading and found many tutorials/blogs on how to create a WebAPI with .Net Core but they all start from a new project and never go much more into depth. The once that really go in-depth are too complex for me ...

I have 3 questions unanswered at the moment although I know that there's probably more than 1 good answer to each of the questions but I think these are the likes of questions that many in my position, beyond the newbie/beginner but not yet a seasoned veteran, have and are searching for so I hope this post helps not just me but many others as well.

Question 1 - Architecture, where to create the API (project)?
There are 3 possibilities:
1 Add APIControllers to the MVC application (organize API-related classes in separate folders)
Benefits

  • quick and easy, everything else is already in place
  • deploys with the solution

Concerns

  • as it is part of the solution it becomes very monolithic, less flexible

Questions

  • can I implement a second authentication/authorization mechanism next to the implemented individual user accounts? (more detailed in the second question which is all about security)

2 Add a WebAPI project to the solution
Benefits

  • better separation but can still use/reference the resources of the other projects
  • probably gives benefits for scaling and tuning?

Questions

  • can I implement a second authentication/authorization mechanism next to the implemented individual user accounts leveraging the Identity of the MVC project? (more detailed in the second question which is all about security)
  • is this project separately published to Azure (or any cloud provider for that matter) using the www.example.com/api path (virtual directory) or is the solution published a whole?

3 Create a separate solution with the WebAPI project and include the data layer project
Benefits

  • full separation although sharing the use of the data layer project
  • completely independent with regards to deployment, scalability etc.

Concerns

  • maybe adds a layer of unnecessary complexity (the API will not handle thousands of requests per second)
  • Everything that is already configured/setup in the MVC project and that is required will need to be redone

Questions

  • can I include the data layer project in the solution (it is then part of 2 solutions) or should I reference it as a dll?

Question 2 - how to implement Authentication/Authorization that resides side-by-side with the Identity individual user account?
This is related only to the first 2 options of the architecture as in the third option the project would be on it's own. The basic question is how to setup more than one authentication mechanism, one for UI users and another for API access.
First there is the choice of Authentication, most of tutorials blogs talk about JWT and Auth (OAuth?). I am not asking what the "best" solution is but which solution would be "preferred" by B2B customers who are the only ones that will use the API.
I am not sure how to redirect to the right authentication: when a request is sent to an API controller method with the Authorize attribute and the user hasn't been authenticated yet it needs to reply with an error.
Currently if a method with the Authorize attribute is executed by an unauthenticated user the user is redirected to the login page as configured in startup.cs:

public void ConfigureServices(IServiceCollection services)
{
...
    services.PostConfigure<CookieAuthenticationOptions>(IdentityConstants.ApplicationScheme,
                opt => {
                    opt.LoginPath = "/User/Login";
...

Do I need to configure this with something like the example I found below:

app.UseWhen(x => (x.Request.Path.StartsWithSegment("/api", StringComparison.OrdinalIgnoreCase)), 
    builder =>
    {
        builder.UseMiddleware<AuthenticationMiddleware>();
    });

or is this configured in a different way?

In the case of creating the API as a separate project should I use the "Multiple startup projects" option? I guess this means that I need to create the whole startup.cs again?

Question 3 - if I want to offer my customers a REST API and an OData API, can I handle this through a single API or do I need to develop a second to support OData?

I know it is lengthy but I'm sure that others are looking for similar information and I'd appreciate any input.

Thanks

0

There are 0 answers