navigation

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

Namespace: Saturn.Endpoint
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 = subcontroller {
    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<'?39910,'?39911,'?39912,'AddOutput,'?39913,'?39914,'?39915,'?39916,'?39917,'?39918> * handler:(HttpContext -> 'Dependency -> Task<'AddOutput>)) -> ControllerState<'?39910,'?39911,'?39912,'AddOutput,'?39913,'?39914,'?39915,'?39916,'?39917,'?39918>

x.Add(state, handler)
Signature: (state:ControllerState<'?39890,'?39891,'?39892,'AddOutput,'?39893,'?39894,'?39895,'?39896,'?39897,'?39898> * handler:(HttpContext -> Task<'AddOutput>)) -> ControllerState<'?39890,'?39891,'?39892,'AddOutput,'?39893,'?39894,'?39895,'?39896,'?39897,'?39898>


CE Custom Operation: add

Operation that should render form for adding new item

x.Create(state, handler)
Signature: (state:ControllerState<'?39990,'?39991,'?39992,'?39993,'?39994,'AddOutput,'?39995,'?39996,'?39997,'?39998> * handler:(HttpContext -> 'Dependency -> Task<'AddOutput>)) -> ControllerState<'?39990,'?39991,'?39992,'?39993,'?39994,'AddOutput,'?39995,'?39996,'?39997,'?39998>

x.Create(state, handler)
Signature: (state:ControllerState<'?39970,'?39971,'?39972,'?39973,'?39974,'CreateOutput,'?39975,'?39976,'?39977,'?39978> * handler:(HttpContext -> Task<'CreateOutput>)) -> ControllerState<'?39970,'?39971,'?39972,'?39973,'?39974,'CreateOutput,'?39975,'?39976,'?39977,'?39978>


CE Custom Operation: create

Operation that creates new item

x.Delete(state, handler)
Signature: (state:ControllerState<'Key,'?40108,'?40109,'?40110,'?40111,'?40112,'?40113,'?40114,'DeleteOutput,'?40115> * handler:(HttpContext -> 'Dependency -> 'Key -> Task<'DeleteOutput>)) -> ControllerState<'Key,'?40108,'?40109,'?40110,'?40111,'?40112,'?40113,'?40114,'DeleteOutput,'?40115>

x.Delete(state, handler)
Signature: (state:ControllerState<'Key,'?40089,'?40090,'?40091,'?40092,'?40093,'?40094,'?40095,'DeleteOutput,'?40096> * handler:(HttpContext -> 'Key -> Task<'DeleteOutput>)) -> ControllerState<'Key,'?40089,'?40090,'?40091,'?40092,'?40093,'?40094,'?40095,'DeleteOutput,'?40096>


CE Custom Operation: delete

Operation that deletes existing item

x.DeleteAll(state, handler)
Signature: (state:ControllerState<'?40148,'?40149,'?40150,'?40151,'?40152,'?40153,'?40154,'?40155,'?40156,'DeleteAllOutput> * handler:(HttpContext -> 'Dependency -> Task<'DeleteAllOutput>)) -> ControllerState<'?40148,'?40149,'?40150,'?40151,'?40152,'?40153,'?40154,'?40155,'?40156,'DeleteAllOutput>

x.DeleteAll(state, handler)
Signature: (state:ControllerState<'?40128,'?40129,'?40130,'?40131,'?40132,'?40133,'?40134,'?40135,'?40136,'DeleteAllOutput> * handler:(HttpContext -> Task<'DeleteAllOutput>)) -> ControllerState<'?40128,'?40129,'?40130,'?40131,'?40132,'?40133,'?40134,'?40135,'?40136,'DeleteAllOutput>


CE Custom Operation: delete_all

Operation that deletes all items

x.Edit(state, handler)
Signature: (state:ControllerState<'Key,'?39950,'?39951,'?39952,'EditOutput,'?39953,'?39954,'?39955,'?39956,'?39957> * handler:(HttpContext -> 'Dependency -> 'Key -> Task<'EditOutput>)) -> ControllerState<'Key,'?39950,'?39951,'?39952,'EditOutput,'?39953,'?39954,'?39955,'?39956,'?39957>

x.Edit(state, handler)
Signature: (state:ControllerState<'Key,'?39931,'?39932,'?39933,'EditOutput,'?39934,'?39935,'?39936,'?39937,'?39938> * handler:(HttpContext -> 'Key -> Task<'EditOutput>)) -> ControllerState<'Key,'?39931,'?39932,'?39933,'EditOutput,'?39934,'?39935,'?39936,'?39937,'?39938>


CE Custom Operation: edit

Operation that should render form for editing existing item

x.ErrorHandler(state, handler)
Signature: (state:ControllerState<'?40211,'?40212,'?40213,'?40214,'?40215,'?40216,'?40217,'?40218,'?40219,'?40220> * handler:(HttpContext -> 'Dependency -> Exception -> HttpFuncResult)) -> ControllerState<'?40211,'?40212,'?40213,'?40214,'?40215,'?40216,'?40217,'?40218,'?40219,'?40220>

x.ErrorHandler(state, handler)
Signature: (state:ControllerState<'?40190,'?40191,'?40192,'?40193,'?40194,'?40195,'?40196,'?40197,'?40198,'?40199> * handler:(HttpContext -> Exception -> HttpFuncResult)) -> ControllerState<'?40190,'?40191,'?40192,'?40193,'?40194,'?40195,'?40196,'?40197,'?40198,'?40199>


CE Custom Operation: error_handler

Define error for the controller

x.Index(state, handler)
Signature: (state:ControllerState<'?39830,'IndexOutput,'?39831,'?39832,'?39833,'?39834,'?39835,'?39836,'?39837,'?39838> * handler:(HttpContext -> 'Dependency -> Task<'IndexOutput>)) -> ControllerState<'?39830,'IndexOutput,'?39831,'?39832,'?39833,'?39834,'?39835,'?39836,'?39837,'?39838>

x.Index(state, handler)
Signature: (state:ControllerState<'?39810,'IndexOutput,'?39811,'?39812,'?39813,'?39814,'?39815,'?39816,'?39817,'?39818> * handler:(HttpContext -> Task<'IndexOutput>)) -> ControllerState<'?39810,'IndexOutput,'?39811,'?39812,'?39813,'?39814,'?39815,'?39816,'?39817,'?39818>


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<'?40169,'?40170,'?40171,'?40172,'?40173,'?40174,'?40175,'?40176,'?40177,'?40178> * handler:HttpHandler) -> ControllerState<'?40169,'?40170,'?40171,'?40172,'?40173,'?40174,'?40175,'?40176,'?40177,'?40178>


CE Custom Operation: not_found_handler

Define not-found handler for the controller

x.Patch(state, handler)
Signature: (state:ControllerState<'Key,'?40069,'?40070,'?40071,'?40072,'?40073,'?40074,'PatchOutput,'?40075,'?40076> * handler:(HttpContext -> 'Dependency -> 'Key -> Task<'PatchOutput>)) -> ControllerState<'Key,'?40069,'?40070,'?40071,'?40072,'?40073,'?40074,'PatchOutput,'?40075,'?40076>

x.Patch(state, handler)
Signature: (state:ControllerState<'Key,'?40050,'?40051,'?40052,'?40053,'?40054,'?40055,'PatchOutput,'?40056,'?40057> * handler:(HttpContext -> 'Key -> Task<'PatchOutput>)) -> ControllerState<'Key,'?40050,'?40051,'?40052,'?40053,'?40054,'?40055,'PatchOutput,'?40056,'?40057>


CE Custom Operation: patch

Operation that patches existing item

x.Plug(state, actions, handler)
Signature: (state:ControllerState<'?40275,'?40276,'?40277,'?40278,'?40279,'?40280,'?40281,'?40282,'?40283,'?40284> * actions:Action list * handler:HttpHandler) -> ControllerState<'?40275,'?40276,'?40277,'?40278,'?40279,'?40280,'?40281,'?40282,'?40283,'?40284>


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> -> Endpoint list

x.Show(state, handler)
Signature: (state:ControllerState<'Key,'?39870,'ShowOutput,'?39871,'?39872,'?39873,'?39874,'?39875,'?39876,'?39877> * handler:(HttpContext -> 'Dependency -> 'Key -> Task<'ShowOutput>)) -> ControllerState<'Key,'?39870,'ShowOutput,'?39871,'?39872,'?39873,'?39874,'?39875,'?39876,'?39877>

x.Show(state, handler)
Signature: (state:ControllerState<'Key,'?39851,'ShowOutput,'?39852,'?39853,'?39854,'?39855,'?39856,'?39857,'?39858> * handler:(HttpContext -> 'Key -> Task<'ShowOutput>)) -> ControllerState<'Key,'?39851,'ShowOutput,'?39852,'?39853,'?39854,'?39855,'?39856,'?39857,'?39858>


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<'?40254,'?40255,'?40256,'?40257,'?40258,'?40259,'?40260,'?40261,'?40262,'?40263> * route:string * handler:('?40254 -> HttpHandler)) -> ControllerState<'?40254,'?40255,'?40256,'?40257,'?40258,'?40259,'?40260,'?40261,'?40262,'?40263>


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,'?40030,'?40031,'?40032,'?40033,'?40034,'UpdateOutput,'?40035,'?40036,'?40037> * handler:(HttpContext -> 'Dependency -> 'Key -> Task<'UpdateOutput>)) -> ControllerState<'Key,'?40030,'?40031,'?40032,'?40033,'?40034,'UpdateOutput,'?40035,'?40036,'?40037>

x.Update(state, handler)
Signature: (state:ControllerState<'Key,'?40011,'?40012,'?40013,'?40014,'?40015,'UpdateOutput,'?40016,'?40017,'?40018> * handler:(HttpContext -> 'Key -> Task<'UpdateOutput>)) -> ControllerState<'Key,'?40011,'?40012,'?40013,'?40014,'?40015,'UpdateOutput,'?40016,'?40017,'?40018>


CE Custom Operation: update

Operation that updates existing item

x.Version(state, version)
Signature: (state:ControllerState<'?40233,'?40234,'?40235,'?40236,'?40237,'?40238,'?40239,'?40240,'?40241,'?40242> * version:string) -> ControllerState<'?40233,'?40234,'?40235,'?40236,'?40237,'?40238,'?40239,'?40240,'?40241,'?40242>


CE Custom Operation: version

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

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