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

Feature/support api gateway proxy events #52

Merged
merged 52 commits into from
Jan 15, 2021

Conversation

IamfromSpace
Copy link
Collaborator

No description provided.

IamfromSpace and others added 30 commits February 10, 2019 12:59
…ure in place, still compile errors. Hi-jacked simple example and needs to be restored.
… the default Runtime and the ApiGatewayRuntime.
…-y, so there's no need to a have a Raw vs Haskell-y type.
…eString, requiring the handler to decode it.
…tent types into the body field of the JSON returned in an ApiGatewayProxyResponse.
…s a parameter to the ApiGatewayProxyRequest.
src/AWS/Lambda/Events/ApiGateway/ProxyRequest.hs Outdated Show resolved Hide resolved
v .: "apiId"
parseJSON _ = mzero

-- TODO: Should also include websocket fields
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Created a card here: #53

Other than adding the fields, is there anything else we need to support websockets from apig?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this is a bit of an odd one. The more I think about it, the more I think that this should be a separate event that maybe has some common models (Identity ab RequestContext maybe). But ultimately it makes a bunch of fields optional if we try to do them together. Which makes sense for JSON, but less so here—where we want to strongly type and communicate guarantees wherever possible.

The downside of the separate is a bunch of boilerplate. The record field destructuring is super useful for these types, but it doesn’t seem to compose for reuse very nicely.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll have to chew on this one a bit more before responding more completely

instance FromJSON a => FromJSON (ProxyRequest a) where
parseJSON (Object v) =
ProxyRequest <$> v .: "path" <*>
(toCIHashMap <$> (v .:? "headers" .!= mempty)) <*>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm slightly surprised there's no constructor that implicitly provides mempty 🤔

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That’s actually a really good point... I wonder if I missed one (or if PRing one in even makes sense).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I skimmed the aeson docs but couldn't find anything that required a monoid instance :/ could be worth contributing a new operator/fn?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given:

Prelude Data.Foldable> :t fold @Maybe
fold @Maybe :: Monoid m => Maybe m -> m

Does toCIHashMap . fold <$> (v .:? "headers) do what you want?

src/AWS/Lambda/Events/ApiGateway/ProxyRequest.hs Outdated Show resolved Hide resolved
@IamfromSpace
Copy link
Collaborator Author

Alrighty, I think I'm finally happy with this interface. I think this is the right balance between "looking like" the AWS examples while still leveraging types, smart constructors, and helpers to hide a lot of the uglier details.

@endgame
Copy link
Contributor

endgame commented Sep 8, 2020

Question: what is the goal of the hal package? If it's to eventually provide a full toolkit for lambda-related stuff, this PR makes a lot of sense here. If it's to provide just a runtime, then maybe a hal-api-gateway package makes more sense? (Probably still in this repo, with a cabal.project file. Something like https://github.com/hedgehogqa/haskell-hedgehog 's repo layout?)

@IamfromSpace
Copy link
Collaborator Author

Question: what is the goal of the hal package?

@endgame , It's a good question, and I'm not sure I've got a totally solid answer. I don't think it's strictly a low level handler, otherwise we would not have provided combinators and a plethora of different runtimes to choose from. I also don't think it'll be a comprehensive toolkit, because there's simply too much ground for this to cover.

I think either we support all official AWS events or we break all common events out into a separate module(s). And I probably lean further towards the latter. However, I also think that many people literally do not realize that Lambda /= Api Gateway Lambda HTTP APIs. The micronaut + Graal runtime for example, doesn't even support any other events (which seems crazy to me). So this event type is so core many people's thinking of Lambda, that I'm not too afraid to include it here--even if it's one of the very few to ever make it in.

In the future, I think one option is to use a separate library, move everything over, and then simply re-export it all here for backwards compatibility. That seems like a manageable approach going forward.

Curious if you've got other thoughts or concerns though :)

@endgame
Copy link
Contributor

endgame commented Sep 18, 2020

many people literally do not realize that Lambda /= Api Gateway Lambda HTTP APIs.

Heh, yes. I've had this problem in other contexts, where overly-"helpful" libraries have made it really hard to work with other event types.

In the future, I think one option is to use a separate library, move everything over, and then simply re-export it all here for backwards compatibility. That seems like a manageable approach going forward.

Split-when-necessary seems like a fine approach, and if you ever want to pare back the re exports you can do it with a major version bump.

One thing I've seen a couple of times: a project starts with foo package, which eventually gets too big. Eventually it splits into foo-core, foo-bar, foo-baz, foo-quux etc, and foo becomes compatibility/convenience re-exports. This seems fine, if hal gets so big that it becomes necessary. At a rate of one module per event type, that might not be necessary.

@IamfromSpace IamfromSpace merged commit 057d4ef into master Jan 15, 2021
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

Successfully merging this pull request may close these issues.

3 participants