Skip to content
This repository was archived by the owner on Nov 27, 2018. It is now read-only.

Add extensions for super simple HTTP service application building #367

Closed
DamianEdwards opened this issue Oct 11, 2016 · 7 comments
Closed

Comments

@DamianEdwards
Copy link
Member

DamianEdwards commented Oct 11, 2016

Some people want to have as little code as possible in a single file (Program.cs) to stand up very simple HTTP services (no, I won't say "micro-services").

In other platforms (Go, Node, etc.) it's generally very easy to get an HTTP server up with some basic dispatching to various request-handling functions based on URL path. Doing this in ASP.NET Core today requires slightly more ceremony (Using IApplicationBuilder, RouteBuilder, a Startup class, etc.) but this can be very easily fixed with a couple of new extension methods in Routing.

Super simple HTTP service application:

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;

namespace NotAMicroService
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var host = new WebHostBuilder()
                .UseKestrel()
                .UseUrls("http://+:8080/") // optional, we default to listening on http://localhost:5000/
                .Configure(app => app
                    .UseRouter(router => router
                        .MapGet("hello/{*name}", (req, res, data) => res.WriteAsync($"Hello, {data.Values["name"]}!"))
                        .MapGet("goodbye/{*name}", (req, res, data) => res.WriteAsync($"Goodbye, {data.Values["name"]}!"))
                        .MapGet("{*name}", (req, res, data) => res.WriteAsync($"Welcome, {data.Values["name"]}!"))
                    )
                )
                .Build();

            host.Run();
        }
    }
}

Extension methods we need to add to Microsoft.AspNetCore.Routing to make this work:

using System;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.DependencyInjection;

namespace Microsoft.AspNetCore.Hosting
{
    public static class WebHostExtensions
    {
        public static IWebHostBuilder UseRouter(this IWebHostBuilder builder, Action<RouteBuilder> routeBuilder)
        {
            return builder
                .ConfigureServices(services => services.AddRouting())
                .Configure(app =>
                {
                    var router = new RouteBuilder(app);
                    routeBuilder(router);
                    app.UseRouter(router.Build());
                });
        }
    }
}
using System;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;

namespace Microsoft.AspNetCore.Hosting
{
    public static class RouteBuilderExtensions
    {
        public static IRouteBuilder MapGet(this IRouteBuilder builder, string template, Func<HttpRequest, HttpResponse, RouteData, Task> handler)
        {
            builder.MapGet(template, context =>
            {
                return handler(context.Request, context.Response, context.GetRouteData());
            });
            return builder;
        }
    }
}
@dustinmoris
Copy link

dustinmoris commented Oct 12, 2016

Hey, I saw this watching yesterday's standup today and think this is a brilliant idea. Can I suggest to add an overload which defines the handler as Func<HttpContext, RouteData, Task> or even just Func<HttpContext, Task> (probably the latter makes more sense)? Also just having the extension method names to be Get, Post, etc. reads much nicer than MapGet and then it already looks very much like other "micro" frameworks.

@DamianEdwards
Copy link
Member Author

@dustinmoris yep agreed, would be nice to have that one too. Not sure about going all the way to just Get, Post, etc. methods. Of course, nothing stopping anybody from creating those extensions methods themselves 😄

@Eilon Eilon added this to the 1.2.0 milestone Nov 27, 2016
@Eilon
Copy link
Member

Eilon commented Nov 27, 2016

@kichalla can you work with folks on finalizing a design, and then implement?

@kichalla
Copy link
Member

cc @rynowak

@rynowak
Copy link
Member

rynowak commented Nov 28, 2016

@DamianEdwards - we already have a bunch of extensions with similar flavour on IRouteBuilder. Hopefully what's there is a good match for what you had in mind or else it's going to get confusing.

https://github.com/aspnet/Routing/blob/dev/src/Microsoft.AspNetCore.Routing/RequestDelegateRouteBuilderExtensions.cs

kichalla added a commit that referenced this issue Dec 12, 2016
kichalla added a commit that referenced this issue Dec 12, 2016
@DamianEdwards DamianEdwards changed the title Add extensions on WebHostBuilder for super simple HTTP service application building Add extensions for super simple HTTP service application building Dec 12, 2016
kichalla added a commit that referenced this issue Dec 19, 2016
@Eilon
Copy link
Member

Eilon commented Dec 21, 2016

Done?? 😄

@Kralizek
Copy link

Kralizek commented Nov 1, 2017

Too late to the party?

How about adding support to DI in the lambda we pass to the extension method? Very similarly to what we already have when authoring a middleware

.UseRouter(router => router
    .MapGet("hello/{*name}", async (HttpRequest req, HttpResponse res, RouteData data, IGreeter greeter) => await myService.GreetAsync(data.Values["name"]))
)

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

6 participants