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

Add beginner friendly examples #1002

Open
kingparra opened this issue Aug 7, 2024 · 4 comments
Open

Add beginner friendly examples #1002

kingparra opened this issue Aug 7, 2024 · 4 comments

Comments

@kingparra
Copy link

Hello! I'm relatively new to Haskell, but experienced with the AWS SDK (using Python and Node).

When I look at examples/EC2.hs, there are a lot of new abstractions to learn. For example, I don't know any of these language extensions other than OverloadedString and haven't worked with Conduit, Lens, or Bytestring before.

Can you add an example that only uses Amazonka and Prelude? Some comments and explicit imports would also be nice.

@endgame
Copy link
Collaborator

endgame commented Aug 8, 2024

Question: Did you find the example in the Amazonka module haddocks. Was it any use to you?

Are you interested in collaborating on this? It's relatively rare for us to have a perspective from an AWS-literate Haskell newbie, and I'd really like to capture something that makes sense to people with your background. At the moment, the examples are all written in a bunch of different ways, to show different alternatives, but there's no guidance for the reader.

I'm on the road at the moment, but I'll go through the examples as they are and see if I can at least remove any unnecessary language extensions.

Prelude is not enough, because that doesn't give you any of the data structures used in requests/responses. I take the spirit of this question as "can we use Prelude only? If not, can we use package base only? If not, can we use bundled libraries only (e.g. bytestring, containers, text)?" — I think the answer is "no", even for the last, but we can provide some simpler examples than what we have now.

As to the libraries that you've called out:

  • ByteString is kinda unavoidable — it's just Haskell's "chunk of bytes" type. I think you'll hit it pretty early on in your Haskell work as soon as you do pretty much anything nontrivial.
  • Conduit is necessary if you want Amazonka to automatically handle a paginated request (like s3:ListObjects); the Conduit is how we interleave the requests and returns of each requested page. However, we can convert the conduit to a list ASAP and have most of the code just working on the result as a list (runConduit (result .| sinkList) or something, off the top of my head).
  • lens is hard to skip, but doable — it makes updating deeply nested records a lot nicer, as well as pulling out bits of responses through several layers of Maybe (AWS are not always disciplined about marking request/response fields as required in their service definitions, so we have a lot of Maybes.) But we could probably get something workable using record updates and pattern matches.

We could probably do that with a few examples from well-understood AWS services. Maybe we should have simple examples for lambda:Invoke, s3:GetObject and s3:PutObject. Streaming file I/O means we'll need conduits for the latter two, but they're so fundamental to AWS use that we should provide simple, copyable code to just upload/download a file. Bonus: we probably want presigned versions of the latter two, also.

@kingparra
Copy link
Author

kingparra commented Aug 8, 2024 via email

@YourFin
Copy link

YourFin commented Oct 4, 2024

Throwing in my hat as a amateur (1) Haskell programmer that /is/ familiar with Lens, Conduit, etc. and uses a bunch of AWS stuff for work, Amazonka was surprisingly difficult to get started with.

My n=1 complaints:

  • amazonka-ec2 isn't on https://amazonka.brendanhay.nz/! I was scratching my head very hard at how to start and stop an EC2 instance before reading something something it's too big to build as part of stackage/hackage, and you need to look at it on local hoogle after adding the dependency to a project.
  • Wait seems really nifty (especially with all the generated instances!), but it's hard to figure out how to work with them. Should I be using some combinators to modify the existing ones, or write my own? Why does the Wait type have multiple Acceptors? What does it mean when an Acceptor returns Nothing vs Just AcceptRetry? What error shows up when it returns AcceptFailure?
  • It's not obvious that I can just write Seconds 12 to represent 12 seconds on the docs for Seconds

(1): ~4 years of Purescript + Haskell in side projects here and there

@justjoheinz
Copy link

I usually always stumble across this section which can be found in nearly all packages:

It is recommended to use generic lenses or optics from packages such as [generic-lens](https://hackage.haskell.org/package/generic-lens) or [optics](https://hackage.haskell.org/package/optics) to modify optional fields and deconstruct responses.

Generated lenses can be found in [Amazonka.EC2.Lens](https://hackage.haskell.org/package/amazonka-ec2-2.0/docs/Amazonka-EC2-Lens.html) and are suitable for use with a lens package such as [lens](http://hackage.haskell.org/package/lens) or [lens-family-core](http://hackage.haskell.org/package/lens-family-core).

It would be nice to somehow have an overview how to use these combinations and their respective advantages or disadvantages.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants