Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FSharp giraffe #3859

Merged
merged 16 commits into from
Jun 12, 2018
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ env:
- "TESTLANG=Dart"
- "TESTLANG=Elixir"
- "TESTLANG=Erlang"
- "TESTLANG=FSharp"
- "TESTLANG=Go"
- "TESTLANG=Groovy"
- "TESTDIR=Haskell/snap"
Expand Down
38 changes: 38 additions & 0 deletions frameworks/FSharp/giraffe/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
[Oo]bj/
[Bb]in/
TestResults/
.nuget/
*.sln.ide/
_ReSharper.*/
.idea/
packages/
artifacts/
PublishProfiles/
.vs/
*.user
*.suo
*.cache
*.docstates
_ReSharper.*
nuget.exe
*net45.csproj
*net451.csproj
*k10.csproj
*.psess
*.vsp
*.pidb
*.userprefs
*DS_Store
*.ncrunchsolution
*.*sdf
*.ipch
*.swp
*~
.build/
.testPublish/
launchSettings.json
BenchmarkDotNet.Artifacts/
BDN.Generated/
binaries/
global.json
*.sln
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the Docker implementation, .gitignore should not be needed.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes it hard to edit the project in Visual Studio and use git without it (as VS creates lots of support files)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fair enough

26 changes: 26 additions & 0 deletions frameworks/FSharp/giraffe/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# girrafe Tests on Linux
This includes tests for plaintext and json serialization.

## Infrastructure Software Versions

**Language**

* F# 4.1

**Platforms**

* .NET Core (Windows and Linux)

**Web Servers**

* [Kestrel](https://github.com/aspnet/KestrelHttpServer)

**Web Stack**

* [giraffe](https://github.com/giraffe-fsharp/Giraffe)
* ASP.NET Core

## Paths & Source for Tests

* [Plaintext](src/App/Programs.fs): "/plaintext"
* [JSON Serialization](src/App/Programs.fs): "/json"
47 changes: 47 additions & 0 deletions frameworks/FSharp/giraffe/benchmark_config.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
{
"framework": "giraffe",
"tests": [
{
"default": {
"plaintext_url": "/plaintext",
"json_url": "/json",
"port": 8080,
"approach": "Realistic",
"classification": "fullstack",
"database": "None",
"framework": "giraffe",
"language": "F#",
"orm": "Raw",
"platform": ".NET",
"flavor": "CoreCLR",
"webserver": "Kestrel",
"os": "Linux",
"database_os": "Linux",
"display_name": "Giraffe",
"notes": "",
"versus": "aspcore"
}
},
{
"jsonutf8": {
Copy link
Contributor

@benaadams benaadams Jun 12, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Call it utf8json to match the library name?

Then it will appear in the listings as giraffe-utf8json as per https://github.com/TechEmpower/FrameworkBenchmarks/blob/master/frameworks/CSharp/aspnetcore/benchmark_config.json#L82

Url can remain the same

"plaintext_url": "/plaintext",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Don't need plaintext entry for this one as nothing is different for plaintext, so no reason to test it twice

"json_url": "/jsonutf8",
"port": 8080,
"approach": "Realistic",
"classification": "fullstack",
"database": "None",
"framework": "giraffe",
"language": "F#",
"orm": "Raw",
"platform": ".NET",
"flavor": "CoreCLR",
"webserver": "Kestrel",
"os": "Linux",
"database_os": "Linux",
"display_name": "Giraffe",
"notes": "",
"versus": "aspcore"
}
}
]
}
12 changes: 12 additions & 0 deletions frameworks/FSharp/giraffe/giraffe-jsonutf8.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM microsoft/dotnet:2.1-sdk-stretch AS build
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

need to rename this docker file to match name change
giraffe-jsonutf8.dockerfile -> giraffe-utf8json.dockerfile

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

oops

WORKDIR /app
COPY src/App .
RUN dotnet publish -c Release -o out

FROM microsoft/dotnet:2.1-aspnetcore-runtime AS runtime
ENV ASPNETCORE_URLS http://+:8080
ENV COMPlus_ReadyToRun 0
WORKDIR /app
COPY --from=build /app/out ./

ENTRYPOINT ["dotnet", "App.dll"]
12 changes: 12 additions & 0 deletions frameworks/FSharp/giraffe/giraffe.dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
FROM microsoft/dotnet:2.1-sdk-stretch AS build
WORKDIR /app
COPY src/App .
RUN dotnet publish -c Release -o out

FROM microsoft/dotnet:2.1-aspnetcore-runtime AS runtime
ENV ASPNETCORE_URLS http://+:8080
ENV COMPlus_ReadyToRun 0
WORKDIR /app
COPY --from=build /app/out ./

ENTRYPOINT ["dotnet", "App.dll"]
27 changes: 27 additions & 0 deletions frameworks/FSharp/giraffe/src/App/App.fsproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<Project Sdk="Microsoft.NET.Sdk.Web">

<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<DebugType>portable</DebugType>
<AssemblyName>App</AssemblyName>
<OutputType>Exe</OutputType>
<EnableDefaultContentItems>false</EnableDefaultContentItems>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.Hosting" Version="2.1.0" />
<PackageReference Include="Microsoft.AspNetCore.Server.Kestrel" Version="2.1.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="2.1.0" />
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we get rid of DI?

<PackageReference Include="Giraffe" Version="1.1.0" />
<PackageReference Include="Utf8Json" Version="1.3.7" />
</ItemGroup>

<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>

<ItemGroup>
<PackageReference Update="FSharp.Core" Version="4.5.0" />
</ItemGroup>

</Project>
36 changes: 36 additions & 0 deletions frameworks/FSharp/giraffe/src/App/Program.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
module App.App

open Microsoft.AspNetCore.Hosting
open Microsoft.AspNetCore.Http
open Giraffe

[<CLIMutable>]
type JsonMessage = { message : string }

let jsonutf8 (data:obj) : HttpHandler =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be data: JsonMessage?

Also is type JsonMessage the equivalent of a C# struct type? (rather than a class type)

The generic Utf8Json Serialize overload for will work better for the struct type (don't change it for the regular one as Json.Net would box it to obj anyway...)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It should be a class
Will add struct for utf8 case + make it generic

fun (_ : HttpFunc) (ctx : HttpContext) ->
let bytes = Utf8Json.JsonSerializer.Serialize(data)
ctx.SetContentType "application/json"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additionally set the content length (bytes.Length); otherwise it will go as chunked encoding which is slightly larger and a little more involved.

ctx.Response.ContentLength <- new System.Nullable<int64>( int64 bytes.Length )
ctx.WriteBytesAsync bytes

let webApp =
choose [
GET >=>
choose [
route "/plaintext" >=> text "Hello, World!"
route "/json" >=> json { message = "Hello, World!" }
route "/jsonutf8" >=> jsonutf8 { message = "Hello, World!" }
]
setStatusCode 404 >=> text "Not Found"
]

[<EntryPoint>]
let main _ =
WebHostBuilder()
.UseKestrel()
.Configure(fun app -> app.UseGiraffe(webApp))
.ConfigureServices(fun services -> services.AddGiraffe() |> ignore)
.Build()
.Run()
0