Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clarification in docs w.r.t setting headers in response #49

Open
hazelweakly opened this issue Oct 2, 2019 · 1 comment
Open

Clarification in docs w.r.t setting headers in response #49

hazelweakly opened this issue Oct 2, 2019 · 1 comment

Comments

@hazelweakly
Copy link

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?

@hazelweakly
Copy link
Author

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.

@hazelweakly hazelweakly changed the title Setting headers in response Clarification in docs w.r.t setting headers in response Oct 4, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant