Introduction
Suave is a lightweight, non-blocking web server. The non-blocking I/O model is efficient and suitable for building fast, scalable network applications. In fact, Suave is written in a completely non-blocking fashion throughout. Suave runs on Linux, OS X and Windows flawlessly.
Suave is inspired in the simplicity of Happstack and born out of the necessity of embedding web server capabilities in my own applications. Still in its early stages Suave supports HTTPS, multiple TCP/IP bindings, Basic Access Authentication, Keep-Alive and HTTP compression.
NuGet
To install Suave, add the following to your paket.dependencies:
|
Or you can use the legacy NuGet command line Package Manager Console:
|
The simplest possible application: Hello World!
The simplest Suave application is a simple HTTP server that greets all visitors
with the string "Hello World!"
open Suave startWebServer defaultConfig (Successful.OK "Hello World!")
The above statement will start a web server on default port 8083 over HTTP.
startWebServer
takes a configuration record and the WebPart (OK "Hello
World")
It's worth noting that with the above, your application will block on
the function call, until you cancel the Async.DefaultCancellationToken
. If you
want to handle disposal of the async yourself, have a look at
startWebServerAsync
.
Ta-daa!
To test the above yourself, paste that code in Hello.fsx
and then invoke it
with fsharpi Hello.fsx
(or fsi Hello.fsx
on Windows). Completely new? Here
are installation instructions on OS X/macOS,
Windows and
Linux. If you have Visual Studio installed you
should be able to find the "F# Interactive" in your menus.
If you are running in an IDE, and not starting Suave via Hello.fsx
, you'll
want to provide a way of stopping the server without having to restart the IDE;
the code below will run the server until a key is pressed in the console window,
then shuts down the server.
open System open System.Threading open Suave [<EntryPoint>] let main argv = let cts = new CancellationTokenSource() let conf = { defaultConfig with cancellationToken = cts.Token } let listening, server = startWebServerAsync conf (Successful.OK "Hello World") Async.Start(server, cts.Token) printfn "Make requests now" Console.ReadKey true |> ignore cts.Cancel() 0 // return an integer exit code
In suave, we have opted to write a lot of documentation inside the code; so just hover the function in your IDE or use an assembly browser to bring out the XML docs. You can also browse our API reference.
Full name: Suave.Web.startWebServer
Full name: Suave.Web.defaultConfig
from Suave
Full name: Suave.Successful.OK
type EntryPointAttribute =
inherit Attribute
new : unit -> EntryPointAttribute
Full name: Microsoft.FSharp.Core.EntryPointAttribute
--------------------
new : unit -> EntryPointAttribute
Full name: temp.main
type CancellationTokenSource =
new : unit -> CancellationTokenSource + 2 overloads
member Cancel : unit -> unit + 1 overload
member CancelAfter : delay:TimeSpan -> unit + 1 overload
member Dispose : unit -> unit
member IsCancellationRequested : bool
member Token : CancellationToken
static member CreateLinkedTokenSource : [<ParamArray>] tokens:CancellationToken[] -> CancellationTokenSource + 1 overload
Full name: System.Threading.CancellationTokenSource
--------------------
CancellationTokenSource() : unit
CancellationTokenSource(delay: TimeSpan) : unit
CancellationTokenSource(millisecondsDelay: int) : unit
Full name: Suave.Web.startWebServerAsync
module Async
from YoLo
--------------------
type Async
static member AsBeginEnd : computation:('Arg -> Async<'T>) -> ('Arg * AsyncCallback * obj -> IAsyncResult) * (IAsyncResult -> 'T) * (IAsyncResult -> unit)
static member AwaitEvent : event:IEvent<'Del,'T> * ?cancelAction:(unit -> unit) -> Async<'T> (requires delegate and 'Del :> Delegate)
static member AwaitIAsyncResult : iar:IAsyncResult * ?millisecondsTimeout:int -> Async<bool>
static member AwaitTask : task:Task -> Async<unit>
static member AwaitTask : task:Task<'T> -> Async<'T>
static member AwaitWaitHandle : waitHandle:WaitHandle * ?millisecondsTimeout:int -> Async<bool>
static member CancelDefaultToken : unit -> unit
static member Catch : computation:Async<'T> -> Async<Choice<'T,exn>>
static member Choice : computations:seq<Async<'T option>> -> Async<'T option>
static member FromBeginEnd : beginAction:(AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg:'Arg1 * beginAction:('Arg1 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * beginAction:('Arg1 * 'Arg2 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromBeginEnd : arg1:'Arg1 * arg2:'Arg2 * arg3:'Arg3 * beginAction:('Arg1 * 'Arg2 * 'Arg3 * AsyncCallback * obj -> IAsyncResult) * endAction:(IAsyncResult -> 'T) * ?cancelAction:(unit -> unit) -> Async<'T>
static member FromContinuations : callback:(('T -> unit) * (exn -> unit) * (OperationCanceledException -> unit) -> unit) -> Async<'T>
static member Ignore : computation:Async<'T> -> Async<unit>
static member OnCancel : interruption:(unit -> unit) -> Async<IDisposable>
static member Parallel : computations:seq<Async<'T>> -> Async<'T []>
static member RunSynchronously : computation:Async<'T> * ?timeout:int * ?cancellationToken:CancellationToken -> 'T
static member Sleep : millisecondsDueTime:int -> Async<unit>
static member Start : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions * ?cancellationToken:CancellationToken -> Task<'T>
static member StartChild : computation:Async<'T> * ?millisecondsTimeout:int -> Async<Async<'T>>
static member StartChildAsTask : computation:Async<'T> * ?taskCreationOptions:TaskCreationOptions -> Async<Task<'T>>
static member StartImmediate : computation:Async<unit> * ?cancellationToken:CancellationToken -> unit
static member StartWithContinuations : computation:Async<'T> * continuation:('T -> unit) * exceptionContinuation:(exn -> unit) * cancellationContinuation:(OperationCanceledException -> unit) * ?cancellationToken:CancellationToken -> unit
static member SwitchToContext : syncContext:SynchronizationContext -> Async<unit>
static member SwitchToNewThread : unit -> Async<unit>
static member SwitchToThreadPool : unit -> Async<unit>
static member TryCancelled : computation:Async<'T> * compensation:(OperationCanceledException -> unit) -> Async<'T>
static member CancellationToken : Async<CancellationToken>
static member DefaultCancellationToken : CancellationToken
Full name: Microsoft.FSharp.Control.Async
--------------------
type Async<'T>
Full name: Microsoft.FSharp.Control.Async<_>
Full name: Microsoft.FSharp.Core.ExtraTopLevelOperators.printfn
static member BackgroundColor : ConsoleColor with get, set
static member Beep : unit -> unit + 1 overload
static member BufferHeight : int with get, set
static member BufferWidth : int with get, set
static member CapsLock : bool
static member Clear : unit -> unit
static member CursorLeft : int with get, set
static member CursorSize : int with get, set
static member CursorTop : int with get, set
static member CursorVisible : bool with get, set
...
Full name: System.Console
Console.ReadKey(intercept: bool) : ConsoleKeyInfo
Full name: Microsoft.FSharp.Core.Operators.ignore
CancellationTokenSource.Cancel(throwOnFirstException: bool) : unit