scotty-format: A Response Format Helper for the Scotty Web Framework
scotty-format is a helper for the Scotty web framework that assists in defining different response formats based on the request’s Accept
header value.
The inspiration for this helper stems from how Rails handles different response formats. In Rails, you can implement actions to respond with various formats based on the Accept
header value.
For example, a client might accept only responses with application/json
content. If the server does not support that format, it should respond with a 406 Not Acceptable
status code.
If the client accepts multiple content types, the response content type will be the best available from the list of all supported types.
If the client does not include any acceptable format, the first defined response format will be used.
Rules for selecting the most appropriate response type are defined in RFC-2616 and are enforced by the http-media library.
The implementation of this helper is inspired by scotty-resource, another helper for Scotty that facilitates the definition of REST resources by strictly following HTTP standards. Scotty-resource defines a WebResource
monad to accumulate callbacks (ActionT
) for each HTTP method you want to support for the resource you are defining. Similarly, scotty-format accumulates callbacks in a ResponseFormat
monad for each format supported by the current action. The respondTo
function then selects the appropriate callback according to the client’s preferences.
Example usage:
1
2
3
4
5
6
7
8
9
10
11
12
main :: IO ()
main = scotty 8080 $ do
get "/hello" $ do
let content = "Hello world!"
respondTo $ do
formatJson $
json $ object ["content" .= content]
formatText $
text content
format "application/vnd.chess-pgn" $ do
setHeader "Content-Type" "application/vnd.chess-pgn; charset=utf-8"
raw $ encodeUtf8 "1. e4"
This function defines a Scotty app with one action (GET /hello
) that responds with three different formats based on the Accept
header value sent by the client.
curl http://localhost:8080/hello
will return a JSON response. Because there is no Accept
header value, the first defined content type will be used by default.
curl -H 'Accept: text/plain' http://localhost:8080/hello
will return a text response.
curl -H 'Accept: image/png' http://localhost:8080/hello
will return a 406 Not Acceptable
error code because there are no callbacks defined to respond with the requested media type.
You can use formatJson
, formatText
, or formatHtml
to accept application/json
, text/plain
, or text/html
media types respectively. To accept a different media type, use the format
function, which accepts a Text
parameter that specifies the media type.
To use this helper, add scotty-format
to your project’s build dependencies list and include the respondTo
and format*
functions.
The source code is available at github.com/potomak/scotty-format under the Apache 2 license.