Skip to content

Instantly share code, notes, and snippets.

@panesofglass
Created February 9, 2016 16:15
Show Gist options
  • Select an option

  • Save panesofglass/27e4fa06cfc158a8f390 to your computer and use it in GitHub Desktop.

Select an option

Save panesofglass/27e4fa06cfc158a8f390 to your computer and use it in GitHub Desktop.
Server MVC OWIN Handlers
(**
* Handlers
*)
let notFound (env: OwinEnv) =
env.[Constants.responseStatusCode] <- 404
env.[Constants.responseReasonPhrase] <- "Not Found"
async.Return()
let methodNotAllowed (env: OwinEnv) =
env.[Constants.responseStatusCode] <- 405
env.[Constants.responseReasonPhrase] <- "Method Not Allowed"
async.Return()
let private makeItemUri env index =
let environ = Environment.toEnvironment env
let baseUri = Uri(environ.GetBaseUri().Value)
if environ.RequestPathBase = "/" then
Uri(baseUri, sprintf "/%i" index)
else
Uri(baseUri, sprintf "%s/%i" environ.RequestPathBase index)
let private makeTodo env (todo: NewTodo) =
{ Url = makeItemUri env todo.Id
Title = todo.Title
Completed = todo.Completed
Order = todo.Order }
(**
* Root resource handlers
*)
let getTodos (env: OwinEnv) = async {
let! todos = store.GetAll()
let todos' = todos |> Array.map (makeTodo env)
let result = serialize todos'
let stream : Stream = unbox env.[Constants.responseBody]
do! stream.AsyncWrite(result, 0, result.Length) }
let postTodo (env: OwinEnv) = async {
// Retrieve the request body
let stream : Stream = unbox env.[Constants.requestBody]
let newTodo : NewTodo = deserialize stream
// TODO: Handle invalid result
// Persist the new todo
let! index = store.Post newTodo
// Return the new todo item
let todo = makeTodo env { newTodo with Id = index }
env.[Constants.responseStatusCode] <- 201
env.[Constants.responseReasonPhrase] <- "Created"
let headers : OwinHeaders = unbox env.[Constants.responseHeaders]
headers.Add("Location", [| todo.Url.AbsoluteUri |])
let result = serialize todo
let stream : Stream = unbox env.[Constants.responseBody]
do! stream.AsyncWrite(result, 0, result.Length) }
let deleteTodos (env: OwinEnv) =
store.Clear()
env.[Constants.responseStatusCode] <- 204
env.[Constants.responseReasonPhrase] <- "No Content"
async.Return()
(**
* Item resource handlers
*)
let getTodo index (env: OwinEnv) = async {
let! todo = store.Get index
match todo with
| Some todo ->
let todo' = makeTodo env todo
let result = serialize todo'
let stream : Stream = unbox env.[Constants.responseBody]
do! stream.AsyncWrite(result, 0, result.Length)
| None -> do! notFound env }
let patchTodo index (env: OwinEnv) = async {
// Retrieve the request body
let stream : Stream = unbox env.[Constants.requestBody]
let patch : TodoPatch = deserialize stream
// TODO: Handle invalid result
// Try to patch the todo
let! newTodo = store.Update(index, patch)
match newTodo with
| Some newTodo ->
// Return the new todo item
let todo = makeTodo env newTodo
env.[Constants.responseStatusCode] <- 200
env.[Constants.responseReasonPhrase] <- "OK"
let result = serialize todo
let stream : Stream = unbox env.[Constants.responseBody]
do! stream.AsyncWrite(result, 0, result.Length)
| None -> do! notFound env }
let deleteTodo index (env: OwinEnv) = async {
let! result = store.Remove index
match result with
| Some _ ->
env.[Constants.responseStatusCode] <- 204
env.[Constants.responseReasonPhrase] <- "No Content"
| None -> do! notFound env }
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment