JetBlack.Http
1.0.0-alpha.7
See the version list below for details.
dotnet add package JetBlack.Http --version 1.0.0-alpha.7
NuGet\Install-Package JetBlack.Http -Version 1.0.0-alpha.7
<PackageReference Include="JetBlack.Http" Version="1.0.0-alpha.7" />
paket add JetBlack.Http --version 1.0.0-alpha.7
#r "nuget: JetBlack.Http, 1.0.0-alpha.7"
// Install JetBlack.Http as a Cake Addin #addin nuget:?package=JetBlack.Http&version=1.0.0-alpha.7&prerelease // Install JetBlack.Http as a Cake Tool #tool nuget:?package=JetBlack.Http&version=1.0.0-alpha.7&prerelease
jetblack-http
This repo contains an HTTP server for dotnet targeting netStandard2.0/2.1, which means it supports .Net Framework, as well as Core. It is based on HttpListener and attempts to maintain the majority of features and supporting classes.
It is a bare-bones implementation, suitable for embedding in applications.
A useful feature of the implementation is that routes may contain variables. for example the route "http://example.com/api/v1/hello/{name:string}/{age:int}" can be routed to an appropriate handler, with the path variables resolved by name and type.
Other features include middleware, fluent configuration, and a replaceable router. Middleware implementations include compression and CORS.
Installation
The package can be installed through nuget.
Usage
This is taken from the examples folder:
using System.Net;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
using JetBlack.Http.Core;
using JetBlack.Http.Middleware;
using JetBlack.Http.Rest;
namespace Example
{
using RestRequest = HttpRequest<RestRouteInfo, RestServerInfo>;
internal class Program
{
static async Task Main(string[] args)
{
using ILoggerFactory loggerFactory = LoggerFactory.Create(builder =>
{
builder.AddConsole();
builder.SetMinimumLevel(LogLevel.Trace);
})
{
var server = new RestServer()
.AddPrefix("http://*:8081/")
.ConfigureRouter(router => router.IgnoreCase = true)
.AddMiddleware(RestCompressionMiddleware.Create())
.AddRoute(SayHello, "/api/v1/helloWorld", "GET")
.AddRoute(SayWithQueryString, "/api/v1/hello") // GET is the default
.AddRoute(SayName, "/api/v1/hello/{name:string}", "GET", "POST")
.AddRoute(SayNameAndAge, "/api/v1/hello/{name:string}/{age:int}");
await server.RunAsync();
}
}
public static Task<HttpResponse> SayHello(RestRequest request)
{
var response = HttpResponse.FromString(
"Hello, World!",
statusCode: HttpStatusCode.OK);
return Task.FromResult(response);
}
public static Task<HttpResponse> SayName(RestRequest request)
{
var name = request.RouteInfo.Matches["name"];
var response = HttpResponse.FromString(
$"Hello, {name}!",
statusCode: HttpStatusCode.OK);
return Task.FromResult(response);
}
public static Task<HttpResponse> SayNameAndAge(RestRequest request)
{
var name = request.RouteInfo.Matches["name"];
var age = request.RouteInfo.Matches["age"];
var response = HttpResponse.FromString(
$"Hello, {name}, you are {age}!",
statusCode: HttpStatusCode.OK);
return Task.FromResult(response);
}
public static Task<HttpResponse> SayWithQueryString(RestRequest request)
{
var name = request.Request.QueryString.Get("name");
var age = request.Request.QueryString.Get("age");
var response = HttpResponse.FromString(
$"Hello, {name ?? "nobody"}, you are {age ?? "a mystery"}!",
statusCode: HttpStatusCode.OK);
return Task.FromResult(response);
}
}
}
State
Two properties are provided for maintaining state on the HttpRequest
object:
RouteInfo
and ServerInfo
. The lifetime of ServerInfo
is the lifetime of
the server. The lifetime of RouteInfo
is that of the invocation of the route.
Routing
The default REST router allows variables in path names: i.e. /foo/bar/{name:string}/{age:int}
.
The available types are: string
, int
, double
, datetime
, path
.
The path
type captures the remaining path as a string, and must be the last variable.
The variables are stored in the Matches
property on the HttpRequest.RouteInfo
.
Middleware
The middleware is nested, is called in order, and has access to both the request and the response.
Given the following middleware:
public static async Task<HttpResponse> FirstMiddleware(
RestRequest request,
Func<RestRequest, CancellationToken, Task<HttpResponse>> handler,
CancellationToken token)
{
Console.WriteLine(">FirstMiddleware");
var response = await handler(request, token);
Console.WriteLine("<FirstMiddleware");
return response;
}
public static async Task<HttpResponse> SecondMiddleware(
RestRequest request,
Func<RestRequest, CancellationToken, Task<HttpResponse>> handler,
CancellationToken token)
{
Console.WriteLine(">SecondMiddleware");
var response = await handler(request, token);
Console.WriteLine("<SecondMiddleware");
return response;
}
The output would be:
>FirstMiddleware
>SecondMiddleware
<SecondMiddleware
<FirstMiddleware
Acknowledgements
This was derived from Cherry.
Product | Versions Compatible and additional computed target framework versions. |
---|---|
.NET | net5.0 was computed. net5.0-windows was computed. net6.0 was computed. net6.0-android was computed. net6.0-ios was computed. net6.0-maccatalyst was computed. net6.0-macos was computed. net6.0-tvos was computed. net6.0-windows was computed. net7.0 was computed. net7.0-android was computed. net7.0-ios was computed. net7.0-maccatalyst was computed. net7.0-macos was computed. net7.0-tvos was computed. net7.0-windows was computed. net8.0 was computed. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. |
.NET Core | netcoreapp2.0 was computed. netcoreapp2.1 was computed. netcoreapp2.2 was computed. netcoreapp3.0 was computed. netcoreapp3.1 was computed. |
.NET Standard | netstandard2.0 is compatible. netstandard2.1 is compatible. |
.NET Framework | net461 was computed. net462 was computed. net463 was computed. net47 was computed. net471 was computed. net472 was computed. net48 was computed. net481 was computed. |
MonoAndroid | monoandroid was computed. |
MonoMac | monomac was computed. |
MonoTouch | monotouch was computed. |
Tizen | tizen40 was computed. tizen60 was computed. |
Xamarin.iOS | xamarinios was computed. |
Xamarin.Mac | xamarinmac was computed. |
Xamarin.TVOS | xamarintvos was computed. |
Xamarin.WatchOS | xamarinwatchos was computed. |
-
.NETStandard 2.0
- Microsoft.Extensions.Configuration (>= 6.0.1)
- Microsoft.Extensions.Configuration.Binder (>= 6.0.0)
- Microsoft.Extensions.Configuration.FileExtensions (>= 6.0.0)
- Microsoft.Extensions.Configuration.Json (>= 6.0.0)
- Microsoft.Extensions.Logging (>= 6.0.0)
- Microsoft.Extensions.Logging.Console (>= 6.0.0)
- System.Net.Http (>= 4.3.4)
-
.NETStandard 2.1
- Microsoft.Extensions.Configuration (>= 6.0.1)
- Microsoft.Extensions.Configuration.Binder (>= 6.0.0)
- Microsoft.Extensions.Configuration.FileExtensions (>= 6.0.0)
- Microsoft.Extensions.Configuration.Json (>= 6.0.0)
- Microsoft.Extensions.Logging (>= 6.0.0)
- Microsoft.Extensions.Logging.Console (>= 6.0.0)
- System.Net.Http (>= 4.3.4)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.
Version | Downloads | Last updated |
---|---|---|
1.0.1 | 267 | 3/18/2023 |
1.0.0 | 213 | 3/18/2023 |
1.0.0-alpha.8 | 94 | 3/18/2023 |
1.0.0-alpha.7 | 100 | 3/11/2023 |
1.0.0-alpha.6 | 87 | 3/10/2023 |
1.0.0-alpha.5 | 87 | 3/5/2023 |
1.0.0-alpha.4 | 136 | 3/4/2023 |
1.0.0-alpha.3 | 92 | 2/27/2023 |
1.0.0-alpha.2 | 92 | 2/27/2023 |
1.0.0-alpha.1 | 90 | 2/27/2023 |