I have created the web application with the web api. The application contains some Controllers
for example TodoController
:
namespace TodoApi.Controllers
{
[Route("api/[controller]")]
public class TodoController : Controller
{
private readonly TodoContext _context;
public TodoController(TodoContext context)
{
_context = context;
}
[HttpGet]
public IEnumerable<TodoItem> GetAll()
{
return _context.TodoItems.ToList();
}
}
}
If I create the GET
request - /api/todo
- I get the list of Todos from database.
I have a list of controllers and api endpoints like above.
I would like distribute this api to another application ideally like middleware - my idea is register in Startup.cs
like this:
public void ConfigureServices(IServiceCollection services)
{
services.AddTodoApi();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
app.UseTodoApi();
}
This will be awesome use case for my api but I don't know how this controllers api endpoints rewrite like middleware and return same JSON data same approache like using classic Controllers
.
How can I write the middleware
in .NET Core
for creating API endpoints
?
Instead of the separate middleware, you may configure the MVC middleware to discovery controllers from another assembly:
// using System.Reflection;
public void ConfigureServices(IServiceCollection services)
{
...
services
.AddMvc()
.AddApplicationPart(typeof(TodoController).GetTypeInfo().Assembly);
Controllers are part of MVC middleware, they are not a separate part of request pipeline (but this is what middlewares are). When you register the custom middleware, it by default invokes on each request and you have HttpContext context
as an input parameter to work with/edit
Request/Response data. But ASP.NET Core provides Map* extensions that are used as a convention for branching the pipeline.
Map branches the request pipeline based on matches of the given request path. If the request path starts with the given path, the branch is executed.
Example:
private static void HandleMapTodo(IApplicationBuilder app)
{
app.Run(async context =>
{
await context.Response.WriteAsync("/api/todo was handled");
});
}
public void Configure(IApplicationBuilder app)
{
app.Map("/api/todo", HandleMapTodo);
}
Note, that as middleware knows nothing about MVC middleware, you have only access to "raw" request and do not have features like model binding or MVC action filters.