navigation

ControllerBuilder<'Key, 'IndexOutput, 'ShowOutput, 'AddOutput, 'EditOutput, 'CreateOutput, 'UpdateOutput, 'PatchOutput, 'DeleteOutput, 'DeleteAllOutput>

Namespace: Saturn
Parent: Controller

Computation expression used to create Saturn controllers - abstraction representing REST-ish endpoint for serving HTML views or returning data. It supports:

  • a set of predefined actions that are automatically mapped to the endpoints following standard conventions
  • embedding sub-controllers for modeling one-to-many relationships
  • versioning
  • adding plugs for a particular action which in principle provides the same mechanism as attributes in ASP.NET MVC applications
  • defining a common error handler for all actions
  • defining a not-found action

The result of the computation expression is a standard Giraffe HttpHandler, which means that it's easily composable with other parts of the ecosytem.

Example:

let commentController userId = controller {
    index (fun ctx -> (sprintf "Comment Index handler for user %i" userId ) |> Controller.text ctx)
    add (fun ctx -> (sprintf "Comment Add handler for user %i" userId ) |> Controller.text ctx)
    show (fun (ctx, id) -> (sprintf "Show comment %s handler for user %i" id userId ) |> Controller.text ctx)
    edit (fun (ctx, id) -> (sprintf "Edit comment %s handler for user %i" id userId )  |> Controller.text ctx)
}

let userControllerVersion1 = controller {
    version 1
    subController "/comments" commentController

    index (fun ctx -> "Index handler version 1" |> Controller.text ctx)
    add (fun ctx -> "Add handler version 1" |> Controller.text ctx)
    show (fun (ctx, id) -> (sprintf "Show handler version 1 - %i" id) |> Controller.text ctx)
    edit (fun (ctx, id) -> (sprintf "Edit handler version 1 - %i" id) |> Controller.text ctx)
}

let userController = controller {
    subController "/comments" commentController

    plug [All] (setHttpHeader "user-controller-common" "123")
    plug [Index; Show] (setHttpHeader "user-controller-specialized" "123")

    index (fun ctx -> "Index handler no version" |> Controller.text ctx)
    add (fun ctx -> "Add handler no version" |> Controller.text ctx)
    show (fun (ctx, id) -> (sprintf "Show handler no version - %i" id) |> Controller.text ctx)
    edit (fun (ctx, id) -> (sprintf "Edit handler no version - %i" id) |> Controller.text ctx)
}
val commentController : userId:'a -> 'b
val userId : 'a
val sprintf : format:Printf.StringFormat<'T> -> 'T
val id : x:'T -> 'T
val userControllerVersion1 : obj
val userController : obj

Name Description
Instance Members
x.Add(state, handler)
Signature: (state:ControllerState<'?41278,'?41279,'?41280,'AddOutput,'?41281,'?41282,'?41283,'?41284,'?41285,'?41286> * handler:(HttpContext -> 'Dependency -> Task<'AddOutput>)) -> ControllerState<'?41278,'?41279,'?41280,'AddOutput,'?41281,'?41282,'?41283,'?41284,'?41285,'?41286>

x.Add(state, handler)
Signature: (state:ControllerState<'?41258,'?41259,'?41260,'AddOutput,'?41261,'?41262,'?41263,'?41264,'?41265,'?41266> * handler:(HttpContext -> Task<'AddOutput>)) -> ControllerState<'?41258,'?41259,'?41260,'AddOutput,'?41261,'?41262,'?41263,'?41264,'?41265,'?41266>


CE Custom Operation: add

Operation that should render form for adding new item

x.CaseInsensitive(state)
Signature: state:ControllerState<'?41622,'?41623,'?41624,'?41625,'?41626,'?41627,'?41628,'?41629,'?41630,'?41631> -> ControllerState<'?41622,'?41623,'?41624,'?41625,'?41626,'?41627,'?41628,'?41629,'?41630,'?41631>


CE Custom Operation: case_insensitive

Toggle case insensitve routing

x.Create(state, handler)
Signature: (state:ControllerState<'?41358,'?41359,'?41360,'?41361,'?41362,'AddOutput,'?41363,'?41364,'?41365,'?41366> * handler:(HttpContext -> 'Dependency -> Task<'AddOutput>)) -> ControllerState<'?41358,'?41359,'?41360,'?41361,'?41362,'AddOutput,'?41363,'?41364,'?41365,'?41366>

x.Create(state, handler)
Signature: (state:ControllerState<'?41338,'?41339,'?41340,'?41341,'?41342,'CreateOutput,'?41343,'?41344,'?41345,'?41346> * handler:(HttpContext -> Task<'CreateOutput>)) -> ControllerState<'?41338,'?41339,'?41340,'?41341,'?41342,'CreateOutput,'?41343,'?41344,'?41345,'?41346>


CE Custom Operation: create

Operation that creates new item

x.Delete(state, handler)
Signature: (state:ControllerState<'Key,'?41476,'?41477,'?41478,'?41479,'?41480,'?41481,'?41482,'DeleteOutput,'?41483> * handler:(HttpContext -> 'Dependency -> 'Key -> Task<'DeleteOutput>)) -> ControllerState<'Key,'?41476,'?41477,'?41478,'?41479,'?41480,'?41481,'?41482,'DeleteOutput,'?41483>

x.Delete(state, handler)
Signature: (state:ControllerState<'Key,'?41457,'?41458,'?41459,'?41460,'?41461,'?41462,'?41463,'DeleteOutput,'?41464> * handler:(HttpContext -> 'Key -> Task<'DeleteOutput>)) -> ControllerState<'Key,'?41457,'?41458,'?41459,'?41460,'?41461,'?41462,'?41463,'DeleteOutput,'?41464>


CE Custom Operation: delete

Operation that deletes existing item

x.DeleteAll(state, handler)
Signature: (state:ControllerState<'?41516,'?41517,'?41518,'?41519,'?41520,'?41521,'?41522,'?41523,'?41524,'DeleteAllOutput> * handler:(HttpContext -> 'Dependency -> Task<'DeleteAllOutput>)) -> ControllerState<'?41516,'?41517,'?41518,'?41519,'?41520,'?41521,'?41522,'?41523,'?41524,'DeleteAllOutput>

x.DeleteAll(state, handler)
Signature: (state:ControllerState<'?41496,'?41497,'?41498,'?41499,'?41500,'?41501,'?41502,'?41503,'?41504,'DeleteAllOutput> * handler:(HttpContext -> Task<'DeleteAllOutput>)) -> ControllerState<'?41496,'?41497,'?41498,'?41499,'?41500,'?41501,'?41502,'?41503,'?41504,'DeleteAllOutput>


CE Custom Operation: delete_all

Operation that deletes all items

x.Edit(state, handler)
Signature: (state:ControllerState<'Key,'?41318,'?41319,'?41320,'EditOutput,'?41321,'?41322,'?41323,'?41324,'?41325> * handler:(HttpContext -> 'Dependency -> 'Key -> Task<'EditOutput>)) -> ControllerState<'Key,'?41318,'?41319,'?41320,'EditOutput,'?41321,'?41322,'?41323,'?41324,'?41325>

x.Edit(state, handler)
Signature: (state:ControllerState<'Key,'?41299,'?41300,'?41301,'EditOutput,'?41302,'?41303,'?41304,'?41305,'?41306> * handler:(HttpContext -> 'Key -> Task<'EditOutput>)) -> ControllerState<'Key,'?41299,'?41300,'?41301,'EditOutput,'?41302,'?41303,'?41304,'?41305,'?41306>


CE Custom Operation: edit

Operation that should render form for editing existing item

x.ErrorHandler(state, handler)
Signature: (state:ControllerState<'?41579,'?41580,'?41581,'?41582,'?41583,'?41584,'?41585,'?41586,'?41587,'?41588> * handler:(HttpContext -> 'Dependency -> Exception -> HttpFuncResult)) -> ControllerState<'?41579,'?41580,'?41581,'?41582,'?41583,'?41584,'?41585,'?41586,'?41587,'?41588>

x.ErrorHandler(state, handler)
Signature: (state:ControllerState<'?41558,'?41559,'?41560,'?41561,'?41562,'?41563,'?41564,'?41565,'?41566,'?41567> * handler:(HttpContext -> Exception -> HttpFuncResult)) -> ControllerState<'?41558,'?41559,'?41560,'?41561,'?41562,'?41563,'?41564,'?41565,'?41566,'?41567>


CE Custom Operation: error_handler

Define error for the controller

x.Index(state, handler)
Signature: (state:ControllerState<'?41198,'IndexOutput,'?41199,'?41200,'?41201,'?41202,'?41203,'?41204,'?41205,'?41206> * handler:(HttpContext -> 'Dependency -> Task<'IndexOutput>)) -> ControllerState<'?41198,'IndexOutput,'?41199,'?41200,'?41201,'?41202,'?41203,'?41204,'?41205,'?41206>

x.Index(state, handler)
Signature: (state:ControllerState<'?41178,'IndexOutput,'?41179,'?41180,'?41181,'?41182,'?41183,'?41184,'?41185,'?41186> * handler:(HttpContext -> Task<'IndexOutput>)) -> ControllerState<'?41178,'IndexOutput,'?41179,'?41180,'?41181,'?41182,'?41183,'?41184,'?41185,'?41186>


CE Custom Operation: index

Operation that should render (or return in case of API controllers) list of data

x.NotFoundHandler(state, handler)
Signature: (state:ControllerState<'?41537,'?41538,'?41539,'?41540,'?41541,'?41542,'?41543,'?41544,'?41545,'?41546> * handler:HttpHandler) -> ControllerState<'?41537,'?41538,'?41539,'?41540,'?41541,'?41542,'?41543,'?41544,'?41545,'?41546>


CE Custom Operation: not_found_handler

Define not-found handler for the controller

x.Patch(state, handler)
Signature: (state:ControllerState<'Key,'?41437,'?41438,'?41439,'?41440,'?41441,'?41442,'PatchOutput,'?41443,'?41444> * handler:(HttpContext -> 'Dependency -> 'Key -> Task<'PatchOutput>)) -> ControllerState<'Key,'?41437,'?41438,'?41439,'?41440,'?41441,'?41442,'PatchOutput,'?41443,'?41444>

x.Patch(state, handler)
Signature: (state:ControllerState<'Key,'?41418,'?41419,'?41420,'?41421,'?41422,'?41423,'PatchOutput,'?41424,'?41425> * handler:(HttpContext -> 'Key -> Task<'PatchOutput>)) -> ControllerState<'Key,'?41418,'?41419,'?41420,'?41421,'?41422,'?41423,'PatchOutput,'?41424,'?41425>


CE Custom Operation: patch

Operation that patches existing item

x.Plug(state, actions, handler)
Signature: (state:ControllerState<'?41664,'?41665,'?41666,'?41667,'?41668,'?41669,'?41670,'?41671,'?41672,'?41673> * actions:Action list * handler:HttpHandler) -> ControllerState<'?41664,'?41665,'?41666,'?41667,'?41668,'?41669,'?41670,'?41671,'?41672,'?41673>


CE Custom Operation: plug

Add a plug that will be run on each of the provided actions.

x.Run(state)
Signature: state:ControllerState<'Key,'IndexOutput,'ShowOutput,'AddOutput,'EditOutput,'CreateOutput,'UpdateOutput,'PatchOutput,'DeleteOutput,'DeleteAllOutput> -> HttpHandler

x.Show(state, handler)
Signature: (state:ControllerState<'Key,'?41238,'ShowOutput,'?41239,'?41240,'?41241,'?41242,'?41243,'?41244,'?41245> * handler:(HttpContext -> 'Dependency -> 'Key -> Task<'ShowOutput>)) -> ControllerState<'Key,'?41238,'ShowOutput,'?41239,'?41240,'?41241,'?41242,'?41243,'?41244,'?41245>

x.Show(state, handler)
Signature: (state:ControllerState<'Key,'?41219,'ShowOutput,'?41220,'?41221,'?41222,'?41223,'?41224,'?41225,'?41226> * handler:(HttpContext -> 'Key -> Task<'ShowOutput>)) -> ControllerState<'Key,'?41219,'ShowOutput,'?41220,'?41221,'?41222,'?41223,'?41224,'?41225,'?41226>


CE Custom Operation: show

Operation that should render (or return in case of API controllers) single entry of data

x.SubController(state, route, handler)
Signature: (state:ControllerState<'?41643,'?41644,'?41645,'?41646,'?41647,'?41648,'?41649,'?41650,'?41651,'?41652> * route:string * handler:('?41643 -> HttpHandler)) -> ControllerState<'?41643,'?41644,'?41645,'?41646,'?41647,'?41648,'?41649,'?41650,'?41651,'?41652>


CE Custom Operation: subController

Inject a controller into the routing table rooted at a given route. All of that controller's actions will be anchored off of the route as a prefix.

x.Update(state, handler)
Signature: (state:ControllerState<'Key,'?41398,'?41399,'?41400,'?41401,'?41402,'UpdateOutput,'?41403,'?41404,'?41405> * handler:(HttpContext -> 'Dependency -> 'Key -> Task<'UpdateOutput>)) -> ControllerState<'Key,'?41398,'?41399,'?41400,'?41401,'?41402,'UpdateOutput,'?41403,'?41404,'?41405>

x.Update(state, handler)
Signature: (state:ControllerState<'Key,'?41379,'?41380,'?41381,'?41382,'?41383,'UpdateOutput,'?41384,'?41385,'?41386> * handler:(HttpContext -> 'Key -> Task<'UpdateOutput>)) -> ControllerState<'Key,'?41379,'?41380,'?41381,'?41382,'?41383,'UpdateOutput,'?41384,'?41385,'?41386>


CE Custom Operation: update

Operation that updates existing item

x.Version(state, version)
Signature: (state:ControllerState<'?41601,'?41602,'?41603,'?41604,'?41605,'?41606,'?41607,'?41608,'?41609,'?41610> * version:string) -> ControllerState<'?41601,'?41602,'?41603,'?41604,'?41605,'?41606,'?41607,'?41608,'?41609,'?41610>


CE Custom Operation: version

Define version of controller. Adds checking of x-controller-version header

x.Yield(arg1)
Signature: '?41166 -> ControllerState<'Key,'IndexOutput,'ShowOutput,'AddOutput,'EditOutput,'CreateOutput,'UpdateOutput,'PatchOutput,'DeleteOutput,'DeleteAllOutput>