Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
An implementation of the Open Web Interface for .NET (OWIN), a .NET Web Server Gateway Interface, written in F#.
F# Shell
Tree: 854446a98d

Fetching latest commit…

Cannot retrieve the latest commit at this time

Failed to load latest commit information.
Frack.Tests
lib
packages
samples
src
tools
.gitignore
LICENSE.txt
README.md
build.bat
build.fsx
frack.nunit
frack.nuspec
frack.sln

README.md

Frack

Frack -- Functional Rack -- is an implementation of OWIN (Open Web Interface for .NET), which has a similar intent as the Python WSGI and JSGI specifications. Frack is similar in implementation to Rack and Jack and owes a lot to those projects.

Frack is developed in F# as it most directly correlates to the Python and JavaScript implementations and provides yet another opportunity to show off the power and elegance of this terrific language.

Goals

  1. Provide a simple, to-the-metal framework for quickly building web applications without a lot of hassle. Frack will run on top of ASP.NET or System.Net.HttpListener.
  2. Provide a similar interface to those already available on other platforms for easier interoperability with those platforms/applications.
  3. Provide a means of using Frack apps as middlewares for other multi-tier applications, similar to Rack middleware.
  4. Allow easy deployment on a range of hosts: IIS via ASP.NET, Kayak, etc.

Usage

Define an app

Takes an OWIN request dictionary and handlers for an OWIN response tuple or exception.

>  // Writes "Howdy!" then echoes the request body.
>  let app request = async {
>    let! body = request |> Request.readToEnd
>    return "200 OK", dict [| ("Content-Type", "text/plain") |],
>           seq { yield box "Howdy!"B
>                 yield box body } }

val app : IDictionary<string,obj> -> Async<string * IDictionary<string,string> * seq<obj>>

Define a middleware

Takes an OWIN app delegate and returns an OWIN app delegate.

> let head app = fun (req: IDictionary<string, obj>) -> async {
>   if (req?RequestMethod :?> string) <> "HEAD" then
>     return! app req
>   else
>     req?RequestMethod <- "GET"
>     let! status, headers, _ = app req
>     return status, headers, Seq.empty }

val head : (IDictionary<string,obj> -> Async<string * IDictionary<string,string> * seq<obj>>) -> (IDictionary<string,obj> -> Async<string * IDictionary<string,string> * seq<obj>>)

Add middlewares to an app.

> // f(g(x)) style
> let myApp = printEnvironment head app

> // using F# pipeline operator
> let myApp = app |> head |> printEnvironment

> // using function composition 
> let myApp = (head >> printEnvironment) app

Other

If this interests you, please also check out Frank.

Team

  • Ryan Riley

Thanks

Something went wrong with that request. Please try again.