Open hazelweakly opened 5 years ago
So, my confusion regarding this ended up being due to a misunderstanding of how things worked between aws, aws lambda, and haskell specific things. I'll summarize the things I've learned in the interim below (and if you'd like I can open up a PR for docs too):
Getting this built on arch linux required installing libgmp-static
from the AUR. Whatevs.
aws gateway does indeed have magical support for a headers property in the JSON response you send through the handler and will propagate it appropriately.
However, all it needs to do is be JSON, so the type doesn't have to be HeaderName, ByteString. I ended up using Aeson's Value and constructing the JSON manually for the headers because I was lazy.
data Response = Response
{ statusCode :: Int
, headers :: Value
, body :: String
} deriving (Generic, ToJSON)
html :: String
html = "<h1>Hello World</h1>"
handler :: Event -> Context -> IO (Either String Response)
handler event context = pure $
Right Response
{ statusCode = 200
, headers = object [
"Content-Type" .= ("text/html" :: String)
]
, body = html
}
was sufficient for me to have the response automatically become HTML when funneled through the api gateway.
I needed to update the handler in the function configuration and it wasn't clear what that handler should be until I read the source code of the generated splice. Running aws lambda update-function-configuration --function-name test --handler src/Lib.handler
fixed things up for me.
I ended up adding the following to my makefile for convenience
update:
aws lambda update-function-code --function-name test --zip-file fileb://build/function.zip
.PHONY: update
Due to not being very familiar with lambdas and aws in general, it was sometimes hard to know what was haskell specific and what was lambda specific. I think it would've been helpful to have the getting started tutorial go all the way to a hello world example, even if just linking to the aws docs for the next steps.
To my surprise, creating a default settings route in the gateway was sufficient because of the json shape I return in my response. I didn't need to screw with the gateway to make it return html ¯\_(ツ)_/¯ so that was nice.
While screwing around with the library, I got the clever idea to try returning html directly from an aws function rather than JSON. In node this is easy to do by just setting the response header ContentType to html.
However, this runtime seems to require that ToJSON be implemented for the response type, but as far as I can see, the headers are supposed to be of type
[(HeaderName, ByteString)]
as specified in the documentation. Of course, bytestring has no ToJSON instance (neither does HeaderName) so GHC rightfully throws a fit.Is there something I'm missing regarding setting headers for the response? Or with the (albeit unusual) usecase of spitting out HTML directly from a function?