Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
dustinmoris committed Nov 22, 2020
2 parents 3b0f5fa + 36256d5 commit cfa0ee0
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 12 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ jobs:
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.301
dotnet-version: 5.0.100
- name: Restore
run: dotnet restore
- name: Build
Expand Down Expand Up @@ -71,7 +71,7 @@ jobs:
- name: Setup .NET Core
uses: actions/setup-dotnet@v1
with:
dotnet-version: 3.1.301
dotnet-version: 5.0.100
- name: Create Release NuGet package
run: |
arrTag=(${GITHUB_REF//\// })
Expand Down
99 changes: 99 additions & 0 deletions DOCUMENTATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -3260,6 +3260,105 @@ let someHttpHandler : HttpHandler =

There's more features available for Giraffe web applications through additional NuGet packages:

### Endpoint Routing

Starting with Giraffe 5.x we introduced a new module called `Giraffe.EndpointRouting`. The endpoint routing module implements an alternative router to Giraffe's default routing functions which integrates with [ASP.NET Core's endpoint routing APIs](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-5.0).

Given the way how ASP.NET Core's Endpoint Routing works this module comes with several benefits (and unfortunately also some minor downsides) in comparison to Giraffe's default router. The main benefit of `Giraffe.EndpointRouting` is that it nicely integrates with the rest of ASP.NET Core and can benefit from everything which Endpoint Routing makes possible. It also means that any performance improvements made to the ASP.NET Core router will directly translate to Giraffe. The downsides are that several existing routing functions couldn't be ported to `Giraffe.EndpointRouting` and routes are case-insensitive by default. Whilst this can be a problem with some applications overall the limitations are minimal and the benefits should greatly outweigh the downsides in the long term. Endpoint Routing is definitely the new preferred option of routing in ASP.NET Core and will undoubtedly see a lot of investment and improvements by the ASP.NET team over the years.

At last it is possible to have the `Giraffe.EndpointRouting` module and Giraffe's default router work side by side, benefiting from Endpoint Routing where possible and keeping the default router elsewhere.

#### Endpoint Routing Basics

In order to make use of Giraffe's endpoint routing functions one has to open the required module first:

```fsharp
open Giraffe.EndpointRouting
```

Giraffe's HTTP handlers remain unchanged regardless if they are used from a typical Giraffe router or the `Giraffe.EndpointRouting` module. This makes porting to the `Giraffe.EndpointRouting` module tremendously easy:

```fsharp
let handler1 : HttpHandler =
fun (_ : HttpFunc) (ctx : HttpContext) ->
ctx.WriteTextAsync "Hello World"
```

Unlike Giraffe's default router (which really is just a big `HttpHandler` function often implemented with the help of the `choose` function) the endpoint router requires a flat list of `Endpoint` functions:

```fsharp
let endpoints =
[
GET => route "/" (text "Hello World")
GET => routef "/%s/%i" handler2
GET => routef "/%s/%s/%s/%i" handler3
subRoute "/sub" [
// Not specifying a http verb means it will listen to all verbs
route "/test" handler1
]
]
```

Then the `Endpoint list` must be initialised with ASP.NET Core's `EndpointMiddleware` instead of being passed into the `GiraffeMiddleware`:

```fsharp
let configureApp (appBuilder : IApplicationBuilder) =
appBuilder
.UseRouting()
.UseEndpoints(fun e -> e.MapGiraffeEndpoints(endpoints))
|> ignore
```

The main differences are:

- Additionally to `HttpHandler` functions there is a new type called `Endpoint`
- The router is a flat list of `Endpoint` functions
- The `GET`, `POST`, `route`, etc. functions map a conventional `HttpHandler` to an `Endpoint` function (when the `Giraffe.EndpointRouting` module has been opened)
- The final `Endpoint list` has to be passed into ASP.NET Core's `EndpointMiddleware` instead of using the `GiraffeMiddleware`

The `MapGiraffeEndpoints` extension method translates those functions into the final `RequestDelegate` functions which the `EndpointMiddleware` relies on and therefore the `Giraffe.EndpointRouting` module doesn't add any extra overhead or runtime cost to ASP.NET Core's endpoint routing resolution.

#### Endpoint Routing Functions

The following routing functions are available as part of the `Giraffe.EndpointRouting` module:

- `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD`, `OPTIONS`, `TRACE`, `CONNECT`
- `route`
- `routef`
- `subRoute`

The `route`, `routef` and `subRoute` handlers are all case-insensitive. Other handlers such as `routex`, `subRoutef` or `choose` are not supported by the `Giraffe.EndpointRouting` module.

The `choose` handler is replaced by composing an `Endpoint list`.

Other routing handlers couldn't be ported like for like, but the ASP.NET Core Endpoint Routing API allows for greater control and better insight into an endpoint by exposing useful helper functions.

Using the `GetRouteData` extension method one can get access to route values and data tokens from within a handler:

```fsharp
open Microsoft.AspNetCore.Routing
let myHandler (foo : int, bar : string) : HttpHandler =
fun (next : HttpFunc) (ctx : HttpContext) ->
let routeData = ctx.GetRouteData()
routeData.Values // Values produced on the current path
routeData.DataTokens // Tokens produced on the current path
sprintf "Yada Yada %i %s" foo bar
|> ctx.WriteTextAsync
```

The `GetEndpoint` extension method returns the endpoint for the currently executed path and can be used to further explore the metadata and other data attached to this endpoint:

```fsharp
let myHandler (foo : int, bar : string) : HttpHandler =
fun (next : HttpFunc) (ctx : HttpContext) ->
let endpoint = ctx.GetEndpoint()
```

For more information about ASP.NET Core Endpoint Routing please refer to the [official documentation](https://docs.microsoft.com/en-us/aspnet/core/fundamentals/routing?view=aspnetcore-5.0).

### TokenRouter

The `Giraffe.TokenRouter` NuGet package exposes an alternative routing `HttpHandler` which is based on top of a [Radix Tree](https://en.wikipedia.org/wiki/Radix_tree). Several routing handlers (e.g.: `routef` and `subRoute`) have been overridden in such a way that path matching and value parsing are significantly faster than using the basic `choose` function.
Expand Down
19 changes: 19 additions & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,25 @@
Release Notes
=============

## 5.0.0-rc-1

Upgraded to .NET 5. The 5.x version of Giraffe is targeting `net5.0` and dropping support for all other target frameworks. If you cannot upgrade a project to .NET 5 yet then stay on an older version of Giraffe until you can. Giraffe has always been a .NET Core centered project and in the .NET Core world (and now .NET 5 world) there is little to no reason why a project should remain on an old .NET Core version for a long time when upgrade paths are mostly as simple as changing the `<TargetFramework>` property in an `.fsproj` file.

### Summary of changes going into 5.0.0-rc-1

- Only supported target framework is .NET 5

- Added `Giraffe.EndpointRouting` namespace with a version of a few routing handlers which integrate with ASP.NET Core's endpoint routing API
- Currently supported are: `route`, `routef`, `subRoute` and HTTP verb handlers such as `GET`, `POST`, `PUT`, etc.
- Check the [Endpoint Routing](https://github.com/giraffe-fsharp/Giraffe/blob/v5.0.0-rc-1/DOCUMENTATION.md#edpoint-routing) documentation for more details
- Or check the [`EndpointRoutingApp` sample app](https://github.com/giraffe-fsharp/Giraffe/tree/v5.0.0-rc-1/samples/EndpointRoutingApp) for how to use `Giraffe.EndpointRouting`
- Replaced `Giraffe.GiraffeViewEngine` with the standalone NuGet package `Giraffe.ViewEngine`
- New `JsonOnlyNegotiationConfig` for setting a content negotiation policy which only supports JSON serialisation (no XML for those who don't need it)
- Added `SystemTextJsonSerializer` which uses `System.Text.Json` for JSON serialisation when configured as the desired JSON serializer in Giraffe
- Improved RegEx http handlers in original (non Endpoint routing) http handlers
- Swapped Markdown docs for XML docs for all functions.
- Added support for complex model binding (see [#416](https://github.com/giraffe-fsharp/Giraffe/issues/416))

## 5.0.0-alpha-003

- Enhanced Endpoint routing with a metadata list (see [PR #437](https://github.com/giraffe-fsharp/Giraffe/pull/437))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<LangVersion>preview</LangVersion>
<TargetFramework>net5.0</TargetFramework>
</PropertyGroup>

<ItemGroup>
Expand Down
6 changes: 3 additions & 3 deletions src/Giraffe/Giraffe.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<NeutralLanguage>en-GB</NeutralLanguage>

<!-- Build settings -->
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<DebugType>portable</DebugType>
<OutputType>Library</OutputType>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
Expand Down Expand Up @@ -51,9 +51,9 @@
<PackageReference Include="Newtonsoft.Json" Version="12.0.*" />
<PackageReference Include="Utf8Json" Version="1.3.*" />
<PackageReference Include="TaskBuilder.fs" Version="2.1.*" />
<PackageReference Include="System.Text.Json" Version="4.7.*" />
<PackageReference Include="System.Text.Json" Version="5.0.*" />
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.0.*" PrivateAssets="All" />
<PackageReference Include="Giraffe.ViewEngine" Version="1.0.*" />
<PackageReference Include="Giraffe.ViewEngine" Version="1.3.*" />
</ItemGroup>

<ItemGroup>
Expand Down
10 changes: 5 additions & 5 deletions tests/Giraffe.Tests/Giraffe.Tests.fsproj
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<TargetFramework>net5.0</TargetFramework>
<AssemblyName>Giraffe.Tests</AssemblyName>
</PropertyGroup>

Expand Down Expand Up @@ -33,13 +33,13 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="3.1.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.6.1" />
<PackageReference Include="Microsoft.AspNetCore.TestHost" Version="5.0.*" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.*" />
<PackageReference Include="System.Runtime.Serialization.Primitives" Version="4.3.0" />
<PackageReference Include="System.Net.Http" Version="4.3.4" />
<PackageReference Include="xunit" Version="2.4.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.1" />
<PackageReference Include="NSubstitute" Version="4.2.1" />
<PackageReference Include="xunit.runner.visualstudio" Version="2.4.*" />
<PackageReference Include="NSubstitute" Version="4.2.*" />
</ItemGroup>

<ItemGroup>
Expand Down

0 comments on commit cfa0ee0

Please sign in to comment.