-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | A runtime environment for Haskell applications running on AWS Lambda. -- -- This library uniquely supports different types of AWS Lambda Handlers -- for your needs/comfort with advanced Haskell. Instead of exposing a -- single function that constructs a Lambda, this library exposes many. @package hal @version 0.4.7 -- | These combinators are for those who need to peek below the abstraction -- of the basic runtimes, for whatever reason. -- -- They map functions (instead of values) to turn basic handlers into -- handlers compatible with the base runtime. These combinators allow us -- to expose functionality across many dimensions in an abstract way. It -- also allows simple building blocks for those who need to "get in the -- middle" or adapt the basic runtimes in new ways without rebuilding -- everything from the ground up. module AWS.Lambda.Combinators -- | Upgrades a handler that uses the IO monad with an Either -- inside into a base runtime handler. -- -- In the example below, we reconstruct ioRuntimeWithContext -- without actually using it. The readerTRuntime expects a handler -- in the form of event -> ReaderT LambdaContext IO result -- (ignoring constraints). By composing it with withIOInterface we -- get a new runtime which expects a function in the form of -- LambdaContext -> event -> IO result which matches that -- of myHandler. -- --
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..))
-- import AWS.Lambda.Runtime (readerTRuntime)
-- import AWS.Lambda.Combinators (withIOInterface)
-- import Data.Aeson (FromJSON)
-- import Data.Text (unpack)
-- import System.Environment (getEnv)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: LambdaContext -> Named -> IO (Either String String)
-- myHandler (LambdaContext { functionName }) (Named { name }) = do
-- greeting <- getEnv "GREETING"
-- return $ if name == "World" then
-- Right $ "Hello, World from " ++ unpack functionName ++ "!"
-- else
-- Left "Can only greet the world."
--
-- main :: IO ()
-- main = (readerTRuntime . withIOInterface) myHandler
--
-- | Deprecated: This combinator is useful when combined with the
-- current mRuntimeWithContext, which is deprecated.
withIOInterface :: (MonadReader c m, MonadIO m) => (c -> b -> IO (Either String a)) -> b -> m a
-- | Upgrades a handler that accepts LambdaContext and an event to
-- return a value inside an Either inside into a base runtime
-- handler.
--
-- In the example below, we reconstruct fallibleRuntimeWithContext
-- without actually using it. The readerTRuntime expects a handler
-- in the form of event -> ReaderT LambdaContext IO result
-- (ignoring constraints). By composing it with
-- withFallibleInterface we get a new runtime which expects a
-- function in the form of LambdaContext -> event -> Either
-- String result which matches that of myHandler.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..))
-- import AWS.Lambda.Runtime (readerTRuntime)
-- import AWS.Lambda.Combinators (withFallibleInterface)
-- import Data.Aeson (FromJSON)
-- import Data.Text (unpack)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: LambdaContext -> Named -> Either String String
-- myHandler (LambdaContext { functionName }) (Named { name }) =
-- if name == "World" then
-- Right $ "Hello, World from " ++ unpack functionName ++ "!"
-- else
-- Left "Can only greet the world."
--
-- main :: IO ()
-- main = (readerTRuntime . withFallibleInterface) myHandler
--
-- | Deprecated: This combinator is useful when combined with the
-- current mRuntimeWithContext, which is deprecated.
withFallibleInterface :: MonadReader c m => (c -> b -> Either String a) -> b -> m a
-- | This combinator takes a handler that accepts both an event and
-- LambdaContext and converts it into a handler that is compatible
-- with the base monadic runtime.
--
-- In the example below, we reconstruct pureRuntimeWithContext
-- without actually using it. The readerTRuntime expects a handler
-- in the form of event -> ReaderT LambdaContext IO result
-- (ignoring constraints). By composing it with withPureInterface
-- we get a new runtime which expects a function in the form of
-- LambdaContext -> event -> result which matches that of
-- myHandler.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..))
-- import AWS.Lambda.Runtime (readerTRuntime)
-- import AWS.Lambda.Combinators (withPureInterface)
-- import Data.Aeson (FromJSON)
-- import Data.Text (unpack)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: LambdaContext -> Named -> String
-- myHandler (LambdaContext { functionName }) (Named { name }) =
-- "Hello, " ++ name ++ " from " ++ unpack functionName ++ "!"
--
-- main :: IO ()
-- main = (readerTRuntime . withPureInterface) myHandler
--
-- | Deprecated: This combinator is useful when combined with the
-- current mRuntimeWithContext, which is deprecated.
withPureInterface :: MonadReader c m => (c -> b -> a) -> b -> m a
-- | An alias of const, this upgrades a handler that does not accept
-- LambdaContext as its first curried argument to one that does.
--
-- This allows us to use other combinators to construct a lambda runtime
-- that accepts a handler that ignores LambdaContext.
--
-- In the example below, we reconstruct pureRuntime without
-- actually using it. The readerTRuntime expects a handler in the
-- form of event -> ReaderT LambdaContext IO result (ignoring
-- constraints). By composing it with withPureInterface we get a
-- new runtime which expects a function in the form of LambdaContext
-- -> event -> result, And then finally we also compose
-- withoutContext so it accepts the signature event ->
-- result which matches that of myHandler.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Runtime (readerTRuntime)
-- import AWS.Lambda.Combinators (withPureInterface, withoutContext)
-- import Data.Aeson (FromJSON)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Named -> String
-- myHandler (Named { name }) =
-- "Hello, " ++ name
--
-- main :: IO ()
-- main = (readerTRuntime . withPureInterface . withoutContext) myHandler
--
withoutContext :: a -> b -> a
-- | This modifies a function to accept a JSON AST (Value), instead of its
-- JSON parsable input. It also assumes that the JSON AST passed in will
-- ALWAYS be convertable into the original input type.
--
-- This allows us to write handlers of the types we're interested in, but
-- then map back to the "native" handler that is only guaranteed JSON
-- (but not necessarily in a useful or restricted structure).
--
-- This is essentially the glue that converts the
-- AWS.Lambda.Runtime.Value to (the more standard)
-- AWS.Lambda.Runtime. While both export a
-- mRuntimeWithContext, the difference is that the Value Runtime
-- makes no attempt to convert the JSON AST, the standard Runtime does.
--
-- Rarely would this function be used directly, and you wouldn't want to
-- use it at all, (directly or indirectly via Runtime runtimes), if you
-- wanted to act on a failure to convert the JSON AST sent to the Lambda.
withInfallibleParse :: FromJSON a => (a -> b) -> Value -> b
module AWS.Lambda.Context
data ClientApplication
ClientApplication :: Text -> Text -> Text -> Text -> ClientApplication
[$sel:appTitle:ClientApplication] :: ClientApplication -> Text
[$sel:appVersionName:ClientApplication] :: ClientApplication -> Text
[$sel:appVersionCode:ClientApplication] :: ClientApplication -> Text
[$sel:appPackageName:ClientApplication] :: ClientApplication -> Text
data ClientContext
ClientContext :: ClientApplication -> Map Text Text -> Map Text Text -> ClientContext
[$sel:client:ClientContext] :: ClientContext -> ClientApplication
[$sel:custom:ClientContext] :: ClientContext -> Map Text Text
[$sel:environment:ClientContext] :: ClientContext -> Map Text Text
data CognitoIdentity
CognitoIdentity :: Text -> Text -> CognitoIdentity
[$sel:identityId:CognitoIdentity] :: CognitoIdentity -> Text
[$sel:identityPoolId:CognitoIdentity] :: CognitoIdentity -> Text
data LambdaContext
LambdaContext :: Text -> Text -> Int -> Text -> Text -> Text -> Text -> Text -> UTCTime -> Maybe ClientContext -> Maybe CognitoIdentity -> LambdaContext
[$sel:functionName:LambdaContext] :: LambdaContext -> Text
[$sel:functionVersion:LambdaContext] :: LambdaContext -> Text
[$sel:functionMemorySize:LambdaContext] :: LambdaContext -> Int
[$sel:logGroupName:LambdaContext] :: LambdaContext -> Text
[$sel:logStreamName:LambdaContext] :: LambdaContext -> Text
[$sel:awsRequestId:LambdaContext] :: LambdaContext -> Text
[$sel:invokedFunctionArn:LambdaContext] :: LambdaContext -> Text
[$sel:xRayTraceId:LambdaContext] :: LambdaContext -> Text
[$sel:deadline:LambdaContext] :: LambdaContext -> UTCTime
[$sel:clientContext:LambdaContext] :: LambdaContext -> Maybe ClientContext
[$sel:identity:LambdaContext] :: LambdaContext -> Maybe CognitoIdentity
getRemainingTime :: MonadIO m => LambdaContext -> m DiffTime
-- | Deprecated: HasLambdaContext will be removed along with the
-- original mRuntimeWithContext. This utility is no longer necessary
-- without it.
class HasLambdaContext r
withContext :: HasLambdaContext r => LambdaContext -> r -> r
defConfig :: DefConfig a => a
-- | Helper for using arbitrary monads with only the LambdaContext in its
-- Reader
-- | Deprecated: runReaderTLambdaContext will be removed along with the
-- original mRuntimeWithContext. This particular approach was
-- problematic, in that it required a default LambdaContext, when in
-- reality, there is no valid instance.
runReaderTLambdaContext :: ReaderT LambdaContext m a -> m a
instance GHC.Classes.Eq AWS.Lambda.Context.ClientApplication
instance GHC.Generics.Generic AWS.Lambda.Context.ClientApplication
instance GHC.Show.Show AWS.Lambda.Context.ClientApplication
instance GHC.Classes.Eq AWS.Lambda.Context.ClientContext
instance GHC.Generics.Generic AWS.Lambda.Context.ClientContext
instance GHC.Show.Show AWS.Lambda.Context.ClientContext
instance GHC.Classes.Eq AWS.Lambda.Context.CognitoIdentity
instance GHC.Generics.Generic AWS.Lambda.Context.CognitoIdentity
instance GHC.Show.Show AWS.Lambda.Context.CognitoIdentity
instance GHC.Classes.Eq AWS.Lambda.Context.LambdaContext
instance GHC.Generics.Generic AWS.Lambda.Context.LambdaContext
instance GHC.Show.Show AWS.Lambda.Context.LambdaContext
instance AWS.Lambda.Context.HasLambdaContext AWS.Lambda.Context.LambdaContext
instance System.Envy.DefConfig AWS.Lambda.Context.LambdaContext
instance Data.Aeson.Types.ToJSON.ToJSON AWS.Lambda.Context.CognitoIdentity
instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Context.CognitoIdentity
instance Data.Aeson.Types.ToJSON.ToJSON AWS.Lambda.Context.ClientContext
instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Context.ClientContext
instance Data.Aeson.Types.ToJSON.ToJSON AWS.Lambda.Context.ClientApplication
instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Context.ClientApplication
-- | This module exposes types used to model incoming proxy requests
-- from AWS API Gateway. These types are a light pass over the incoming
-- JSON representation.
module AWS.Lambda.Events.ApiGateway.ProxyRequest
-- | This type is for representing events that come from API Gateway via
-- the Lambda Proxy integration (forwarding HTTP data directly, rather
-- than a custom integration). It will automatically decode the event
-- that comes in.
--
-- The ProxyRequest notably has one parameter for the type of
-- information returned by the API Gateway's custom authorizer (if
-- applicable). This type must also implement FromJSON so that it can be
-- decoded. If you do not expect this data to be populated we recommended
-- using the NoAuthorizer type exported from this module (which is
-- just an alias for Value). If there _must not_ be authorizer
-- populated (this is unlikely) then use the StrictlyNoAuthorizer
-- type.
--
--
-- {-# LANGUAGE NamedFieldPuns #-}
-- {-# LANGUAGE DuplicateRecordFields #-}
--
-- module Main where
--
-- import AWS.Lambda.Runtime (pureRuntime)
-- import AWS.Lambda.Events.ApiGateway.ProxyRequest (ProxyRequest(..), NoAuthorizer)
-- import AWS.Lambda.Events.ApiGateway.ProxyResponse (ProxyResponse(..), textPlain, forbidden403, ok200)
--
-- myHandler :: ProxyRequest NoAuthorizer -> ProxyResponse
-- myHandler ProxyRequest { httpMethod = "GET", path = "/say_hello" } =
-- ProxyResponse
-- { status = ok200
-- , body = textPlain "Hello"
-- , headers = mempty
-- , multiValueHeaders = mempty
-- }
-- myHandler _ =
-- ProxyResponse
-- { status = forbidden403
-- , body = textPlain "Forbidden"
-- , headers = mempty
-- , multiValueHeaders = mempty
-- }
--
-- main :: IO ()
-- main = pureRuntime myHandler
--
data ProxyRequest a
ProxyRequest :: Text -> HashMap (CI Text) Text -> HashMap (CI Text) [Text] -> HashMap Text Text -> HashMap Text Text -> RequestContext a -> Text -> Text -> HashMap Text Text -> HashMap Text [Text] -> ByteString -> ProxyRequest a
[$sel:path:ProxyRequest] :: ProxyRequest a -> Text
[$sel:headers:ProxyRequest] :: ProxyRequest a -> HashMap (CI Text) Text
[$sel:multiValueHeaders:ProxyRequest] :: ProxyRequest a -> HashMap (CI Text) [Text]
[$sel:pathParameters:ProxyRequest] :: ProxyRequest a -> HashMap Text Text
[$sel:stageVariables:ProxyRequest] :: ProxyRequest a -> HashMap Text Text
[$sel:requestContext:ProxyRequest] :: ProxyRequest a -> RequestContext a
[$sel:resource:ProxyRequest] :: ProxyRequest a -> Text
[$sel:httpMethod:ProxyRequest] :: ProxyRequest a -> Text
[$sel:queryStringParameters:ProxyRequest] :: ProxyRequest a -> HashMap Text Text
[$sel:multiValueQueryStringParameters:ProxyRequest] :: ProxyRequest a -> HashMap Text [Text]
[$sel:body:ProxyRequest] :: ProxyRequest a -> ByteString
data RequestContext a
RequestContext :: Text -> Text -> Maybe a -> Text -> Text -> Maybe Text -> Text -> Identity -> Maybe Text -> Text -> Text -> Maybe Text -> Text -> RequestContext a
[$sel:path:RequestContext] :: RequestContext a -> Text
[$sel:accountId:RequestContext] :: RequestContext a -> Text
[$sel:authorizer:RequestContext] :: RequestContext a -> Maybe a
[$sel:resourceId:RequestContext] :: RequestContext a -> Text
[$sel:stage:RequestContext] :: RequestContext a -> Text
[$sel:domainPrefix:RequestContext] :: RequestContext a -> Maybe Text
[$sel:requestId:RequestContext] :: RequestContext a -> Text
[$sel:identity:RequestContext] :: RequestContext a -> Identity
[$sel:domainName:RequestContext] :: RequestContext a -> Maybe Text
[$sel:resourcePath:RequestContext] :: RequestContext a -> Text
[$sel:httpMethod:RequestContext] :: RequestContext a -> Text
[$sel:extendedRequestId:RequestContext] :: RequestContext a -> Maybe Text
[$sel:apiId:RequestContext] :: RequestContext a -> Text
data Identity
Identity :: Maybe Text -> Maybe Text -> Maybe Text -> Maybe Text -> Maybe Text -> Text -> Maybe Text -> Maybe Text -> Maybe Text -> Maybe Text -> Maybe Text -> Maybe Text -> Maybe Text -> Identity
[$sel:cognitoIdentityPoolId:Identity] :: Identity -> Maybe Text
[$sel:accountId:Identity] :: Identity -> Maybe Text
[$sel:cognitoIdentityId:Identity] :: Identity -> Maybe Text
[$sel:caller:Identity] :: Identity -> Maybe Text
[$sel:apiKey:Identity] :: Identity -> Maybe Text
[$sel:sourceIp:Identity] :: Identity -> Text
[$sel:accessKey:Identity] :: Identity -> Maybe Text
[$sel:cognitoAuthenticationType:Identity] :: Identity -> Maybe Text
[$sel:cognitoAuthenticationProvider:Identity] :: Identity -> Maybe Text
[$sel:userArn:Identity] :: Identity -> Maybe Text
[$sel:apiKeyId:Identity] :: Identity -> Maybe Text
[$sel:userAgent:Identity] :: Identity -> Maybe Text
[$sel:user:Identity] :: Identity -> Maybe Text
-- | For ignoring API Gateway custom authorizer values
type NoAuthorizer = Value
-- | For ensuring that there were no API Gateway custom authorizer values
-- (this is not likely to be useful, you probably want
-- NoAuthorizer)
type StrictlyNoAuthorizer = Void
instance GHC.Generics.Generic AWS.Lambda.Events.ApiGateway.ProxyRequest.Identity
instance GHC.Generics.Generic (AWS.Lambda.Events.ApiGateway.ProxyRequest.ProxyRequest a)
instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (AWS.Lambda.Events.ApiGateway.ProxyRequest.ProxyRequest a)
instance Data.Aeson.Types.FromJSON.FromJSON a => Data.Aeson.Types.FromJSON.FromJSON (AWS.Lambda.Events.ApiGateway.ProxyRequest.RequestContext a)
instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.ApiGateway.ProxyRequest.Identity
-- | This module enable exposes the required types for responding to API
-- Gateway Proxy Events. Responses must return a status, body, and
-- optionaly headers. Multiple smart contructors and helpers are provided
-- to help encapsulated details like header case-insensitivity, multiple
-- header copies, correct base64 encoding, and default content type.
module AWS.Lambda.Events.ApiGateway.ProxyResponse
-- | A response returned to an API Gateway when using the HTTP Lambda Proxy
-- integration. ContentType will be set based on the ProxyBody
-- (recommended) if a value is not present in the headers field.
--
-- This type can be constructed explicity or via the smart constructor
-- response. Headers can then be added incrementally with
-- addHeader or setHeader. The smart constructor pattern is
-- recommended because it avoids some of the awkwardness of dealing with
-- the multiValueHeaders field's type.
--
--
-- {-# LANGUAGE NamedFieldPuns #-}
-- {-# LANGUAGE DuplicateRecordFields #-}
-- {-# LANGUAGE OverloadedStrings #-}
--
-- module Main where
--
-- import AWS.Lambda.Runtime (pureRuntime)
-- import AWS.Lambda.Events.ApiGateway.ProxyRequest (ProxyRequest(..), NoAuthorizer)
-- import AWS.Lambda.Events.ApiGateway.ProxyResponse (ProxyResponse(..), textPlain, forbidden403, ok200, response)
--
-- myHandler :: ProxyRequest NoAuthorizer -> ProxyResponse
-- myHandler ProxyRequest { httpMethod = "GET", path = "/say_hello" } =
-- -- Smart Constructor and added header (recommended)
-- addHeader "My-Custom-Header" Value $
-- response ok200 $ textPlain "Hello"
-- myHandler _ =
-- -- Explicit Construction (not recommended)
-- ProxyResponse
-- { status = forbidden403
-- , body = textPlain "Forbidden"
-- , multiValueHeaders =
-- fromList [(mk "My-Custom-Header", ["Other Value])]
-- }
--
-- main :: IO ()
-- main = pureRuntime myHandler
--
data ProxyResponse
ProxyResponse :: Status -> HashMap (CI Text) [Text] -> ProxyBody -> ProxyResponse
[$sel:status:ProxyResponse] :: ProxyResponse -> Status
[$sel:multiValueHeaders:ProxyResponse] :: ProxyResponse -> HashMap (CI Text) [Text]
[$sel:body:ProxyResponse] :: ProxyResponse -> ProxyBody
-- | Smart constructor for creating a ProxyResponse from a status and a
-- body
response :: Status -> ProxyBody -> ProxyResponse
-- | Add a header to the ProxyResponse. If there was already a value for
-- this header, this one is added, meaning the response will
-- include multiple copies of this header (valid by the HTTP spec). This
-- does NOT replace any previous headers or their values.
addHeader :: Text -> Text -> ProxyResponse -> ProxyResponse
-- | Set a header to the ProxyResponse. If there were any previous values
-- for this header they are all replaced by this new value.
setHeader :: Text -> Text -> ProxyResponse -> ProxyResponse
-- | Type that represents the body returned to an API Gateway when using
-- HTTP Lambda Proxy integration. It is highly recommended that you do
-- not use this type directly, and instead use the smart constructors
-- exposed such as textPlain, applicationJson, and
-- genericBinary. These make sure that the base64 encodings work
-- transparently.
data ProxyBody
ProxyBody :: Text -> Text -> Bool -> ProxyBody
[$sel:contentType:ProxyBody] :: ProxyBody -> Text
[$sel:serialized:ProxyBody] :: ProxyBody -> Text
[$sel:isBase64Encoded:ProxyBody] :: ProxyBody -> Bool
-- | Smart constructor for creating a simple body of text.
textPlain :: Text -> ProxyBody
-- | Smart constructor for creating a simple body of JSON.
applicationJson :: ToJSON a => a -> ProxyBody
-- | Smart constructor for creating a ProxyBody with an arbitrary
-- ByteString of the chosen content type. Use this smart constructor to
-- avoid invalid JSON representations of binary data.
--
-- From here it is easy to make more specific body constructors:
--
-- -- imageGif :: ByteString -> ProxyBody -- imageGif = genericBinary "image/gif" -- -- imageJpeg :: ByteString -> ProxyBody -- imageJpeg = genericBinary "image/jpeg" --genericBinary :: Text -> ByteString -> ProxyBody -- | Network Authentication Required 511 (RFC 6585) networkAuthenticationRequired511 :: Status -- | Network Authentication Required 511 (RFC 6585) status511 :: Status -- | HTTP Version Not Supported 505 httpVersionNotSupported505 :: Status -- | HTTP Version Not Supported 505 status505 :: Status -- | Gateway Timeout 504 gatewayTimeout504 :: Status -- | Gateway Timeout 504 status504 :: Status -- | Service Unavailable 503 serviceUnavailable503 :: Status -- | Service Unavailable 503 status503 :: Status -- | Bad Gateway 502 badGateway502 :: Status -- | Bad Gateway 502 status502 :: Status -- | Not Implemented 501 notImplemented501 :: Status -- | Not Implemented 501 status501 :: Status -- | Internal Server Error 500 internalServerError500 :: Status -- | Internal Server Error 500 status500 :: Status -- | Request Header Fields Too Large 431 (RFC 6585) requestHeaderFieldsTooLarge431 :: Status -- | Request Header Fields Too Large 431 (RFC 6585) status431 :: Status -- | Too Many Requests 429 (RFC 6585) tooManyRequests429 :: Status -- | Too Many Requests 429 (RFC 6585) status429 :: Status -- | Precondition Required 428 (RFC 6585) preconditionRequired428 :: Status -- | Precondition Required 428 (RFC 6585) status428 :: Status -- | Upgrade Required 426 -- (https://tools.ietf.org/html/rfc7231#section-6.5.15) upgradeRequired426 :: Status -- | Upgrade Required 426 -- (https://tools.ietf.org/html/rfc7231#section-6.5.15) status426 :: Status -- | Unprocessable Entity 422 (RFC 4918) unprocessableEntity422 :: Status -- | Unprocessable Entity 422 (RFC 4918) status422 :: Status -- | I'm a teapot 418 imATeapot418 :: Status -- | I'm a teapot 418 status418 :: Status -- | Expectation Failed 417 expectationFailed417 :: Status -- | Expectation Failed 417 status417 :: Status -- | Requested Range Not Satisfiable 416 requestedRangeNotSatisfiable416 :: Status -- | Requested Range Not Satisfiable 416 status416 :: Status -- | Unsupported Media Type 415 unsupportedMediaType415 :: Status -- | Unsupported Media Type 415 status415 :: Status -- | Request-URI Too Long 414 requestURITooLong414 :: Status -- | Request-URI Too Long 414 status414 :: Status -- | Request Entity Too Large 413 requestEntityTooLarge413 :: Status -- | Request Entity Too Large 413 status413 :: Status -- | Precondition Failed 412 preconditionFailed412 :: Status -- | Precondition Failed 412 status412 :: Status -- | Length Required 411 lengthRequired411 :: Status -- | Length Required 411 status411 :: Status -- | Gone 410 gone410 :: Status -- | Gone 410 status410 :: Status -- | Conflict 409 conflict409 :: Status -- | Conflict 409 status409 :: Status -- | Request Timeout 408 requestTimeout408 :: Status -- | Request Timeout 408 status408 :: Status -- | Proxy Authentication Required 407 proxyAuthenticationRequired407 :: Status -- | Proxy Authentication Required 407 status407 :: Status -- | Not Acceptable 406 notAcceptable406 :: Status -- | Not Acceptable 406 status406 :: Status -- | Method Not Allowed 405 methodNotAllowed405 :: Status -- | Method Not Allowed 405 status405 :: Status -- | Not Found 404 notFound404 :: Status -- | Not Found 404 status404 :: Status -- | Forbidden 403 forbidden403 :: Status -- | Forbidden 403 status403 :: Status -- | Payment Required 402 paymentRequired402 :: Status -- | Payment Required 402 status402 :: Status -- | Unauthorized 401 unauthorized401 :: Status -- | Unauthorized 401 status401 :: Status -- | Bad Request 400 badRequest400 :: Status -- | Bad Request 400 status400 :: Status -- | Permanent Redirect 308 permanentRedirect308 :: Status -- | Permanent Redirect 308 status308 :: Status -- | Temporary Redirect 307 temporaryRedirect307 :: Status -- | Temporary Redirect 307 status307 :: Status -- | Use Proxy 305 useProxy305 :: Status -- | Use Proxy 305 status305 :: Status -- | Not Modified 304 notModified304 :: Status -- | Not Modified 304 status304 :: Status -- | See Other 303 seeOther303 :: Status -- | See Other 303 status303 :: Status -- | Found 302 found302 :: Status -- | Found 302 status302 :: Status -- | Moved Permanently 301 movedPermanently301 :: Status -- | Moved Permanently 301 status301 :: Status -- | Multiple Choices 300 multipleChoices300 :: Status -- | Multiple Choices 300 status300 :: Status -- | Partial Content 206 partialContent206 :: Status -- | Partial Content 206 status206 :: Status -- | Reset Content 205 resetContent205 :: Status -- | Reset Content 205 status205 :: Status -- | No Content 204 noContent204 :: Status -- | No Content 204 status204 :: Status -- | Non-Authoritative Information 203 nonAuthoritative203 :: Status -- | Non-Authoritative Information 203 status203 :: Status -- | Accepted 202 accepted202 :: Status -- | Accepted 202 status202 :: Status -- | Created 201 created201 :: Status -- | Created 201 status201 :: Status -- | OK 200 ok200 :: Status -- | OK 200 status200 :: Status -- | Switching Protocols 101 switchingProtocols101 :: Status -- | Switching Protocols 101 status101 :: Status -- | Continue 100 continue100 :: Status -- | Continue 100 status100 :: Status -- | HTTP Status. -- -- Only the statusCode is used for comparisons. -- -- Please use mkStatus to create status codes from code and -- message, or the Enum instance or the status code constants -- (like ok200). There might be additional record members in the -- future. -- -- Note that the Show instance is only for debugging. data Status Status :: Int -> ByteString -> Status [statusCode] :: Status -> Int [statusMessage] :: Status -> ByteString instance GHC.Show.Show AWS.Lambda.Events.ApiGateway.ProxyResponse.ProxyBody instance GHC.Show.Show AWS.Lambda.Events.ApiGateway.ProxyResponse.ProxyResponse instance Data.Aeson.Types.ToJSON.ToJSON AWS.Lambda.Events.ApiGateway.ProxyResponse.ProxyResponse module AWS.Lambda.Events.S3 data PrincipalIdentity PrincipalIdentity :: Text -> PrincipalIdentity [$sel:principalId:PrincipalIdentity] :: PrincipalIdentity -> Text newtype Records Records :: [S3Event] -> Records [$sel:records:Records] :: Records -> [S3Event] data RequestParameters RequestParameters :: Text -> RequestParameters [$sel:sourceIPAddress:RequestParameters] :: RequestParameters -> Text data ResponseElements ResponseElements :: Text -> Text -> ResponseElements [$sel:amazonId:ResponseElements] :: ResponseElements -> Text [$sel:amazonRequestId:ResponseElements] :: ResponseElements -> Text data S3Bucket S3Bucket :: Text -> Text -> PrincipalIdentity -> S3Bucket [$sel:arn:S3Bucket] :: S3Bucket -> Text [$sel:name:S3Bucket] :: S3Bucket -> Text [$sel:ownerIdentity:S3Bucket] :: S3Bucket -> PrincipalIdentity data S3Config S3Config :: S3Bucket -> Text -> S3Object -> Text -> S3Config [$sel:bucket:S3Config] :: S3Config -> S3Bucket [$sel:configurationId:S3Config] :: S3Config -> Text [$sel:object:S3Config] :: S3Config -> S3Object [$sel:s3SchemaVersion:S3Config] :: S3Config -> Text -- | Event data sent by S3 when triggering a Lambda. data S3Event S3Event :: Text -> Text -> Text -> UTCTime -> Text -> RequestParameters -> ResponseElements -> S3Config -> PrincipalIdentity -> S3Event [$sel:awsRegion:S3Event] :: S3Event -> Text [$sel:eventName:S3Event] :: S3Event -> Text [$sel:eventSource:S3Event] :: S3Event -> Text [$sel:eventTime:S3Event] :: S3Event -> UTCTime [$sel:eventVersion:S3Event] :: S3Event -> Text [$sel:requestParameters:S3Event] :: S3Event -> RequestParameters [$sel:responseElements:S3Event] :: S3Event -> ResponseElements [$sel:s3:S3Event] :: S3Event -> S3Config [$sel:userIdentity:S3Event] :: S3Event -> PrincipalIdentity -- | S3 object representations based on event type received. -- -- Currently only Put/Delete events can trigger Lambdas data S3Object PutObject :: Text -> Text -> Text -> Int -> S3Object [$sel:eTag:PutObject] :: S3Object -> Text [$sel:sequencer:PutObject] :: S3Object -> Text [$sel:key:PutObject] :: S3Object -> Text [$sel:size:PutObject] :: S3Object -> Int DeleteObject :: Text -> Text -> S3Object [$sel:sequencer:PutObject] :: S3Object -> Text [$sel:key:PutObject] :: S3Object -> Text instance GHC.Generics.Generic AWS.Lambda.Events.S3.PrincipalIdentity instance GHC.Classes.Eq AWS.Lambda.Events.S3.PrincipalIdentity instance GHC.Show.Show AWS.Lambda.Events.S3.PrincipalIdentity instance GHC.Generics.Generic AWS.Lambda.Events.S3.S3Bucket instance GHC.Classes.Eq AWS.Lambda.Events.S3.S3Bucket instance GHC.Show.Show AWS.Lambda.Events.S3.S3Bucket instance GHC.Classes.Eq AWS.Lambda.Events.S3.ResponseElements instance GHC.Show.Show AWS.Lambda.Events.S3.ResponseElements instance GHC.Generics.Generic AWS.Lambda.Events.S3.RequestParameters instance GHC.Classes.Eq AWS.Lambda.Events.S3.RequestParameters instance GHC.Show.Show AWS.Lambda.Events.S3.RequestParameters instance GHC.Generics.Generic AWS.Lambda.Events.S3.S3Object instance GHC.Classes.Eq AWS.Lambda.Events.S3.S3Object instance GHC.Show.Show AWS.Lambda.Events.S3.S3Object instance GHC.Generics.Generic AWS.Lambda.Events.S3.S3Config instance GHC.Classes.Eq AWS.Lambda.Events.S3.S3Config instance GHC.Show.Show AWS.Lambda.Events.S3.S3Config instance GHC.Generics.Generic AWS.Lambda.Events.S3.S3Event instance GHC.Classes.Eq AWS.Lambda.Events.S3.S3Event instance GHC.Show.Show AWS.Lambda.Events.S3.S3Event instance GHC.Classes.Eq AWS.Lambda.Events.S3.Records instance GHC.Show.Show AWS.Lambda.Events.S3.Records instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.S3.Records instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.S3.S3Event instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.S3.S3Config instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.S3.S3Object instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.S3.RequestParameters instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.S3.ResponseElements instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.S3.S3Bucket instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.S3.PrincipalIdentity module AWS.Lambda.Events.SQS newtype Records Records :: [SQSEvent] -> Records [$sel:records:Records] :: Records -> [SQSEvent] data Attributes Attributes :: Text -> Text -> Text -> Text -> Attributes [$sel:approximateReceiveCount:Attributes] :: Attributes -> Text [$sel:sentTimestamp:Attributes] :: Attributes -> Text [$sel:senderId:Attributes] :: Attributes -> Text [$sel:approximateFirstReceiveTimestamp:Attributes] :: Attributes -> Text data SQSEvent SQSEvent :: Text -> Text -> Text -> Attributes -> Map Text Text -> Text -> Text -> Text -> Text -> SQSEvent [$sel:messageId:SQSEvent] :: SQSEvent -> Text [$sel:receiptHandle:SQSEvent] :: SQSEvent -> Text [$sel:body:SQSEvent] :: SQSEvent -> Text [$sel:attributes:SQSEvent] :: SQSEvent -> Attributes [$sel:messageAttributes:SQSEvent] :: SQSEvent -> Map Text Text [$sel:md5OfBody:SQSEvent] :: SQSEvent -> Text [$sel:eventSource:SQSEvent] :: SQSEvent -> Text [$sel:eventSourceARN:SQSEvent] :: SQSEvent -> Text [$sel:awsRegion:SQSEvent] :: SQSEvent -> Text instance GHC.Classes.Eq AWS.Lambda.Events.SQS.Attributes instance GHC.Show.Show AWS.Lambda.Events.SQS.Attributes instance GHC.Generics.Generic AWS.Lambda.Events.SQS.SQSEvent instance GHC.Classes.Eq AWS.Lambda.Events.SQS.SQSEvent instance GHC.Show.Show AWS.Lambda.Events.SQS.SQSEvent instance GHC.Classes.Eq AWS.Lambda.Events.SQS.Records instance GHC.Show.Show AWS.Lambda.Events.SQS.Records instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.SQS.Records instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.SQS.SQSEvent instance Data.Aeson.Types.FromJSON.FromJSON AWS.Lambda.Events.SQS.Attributes module AWS.Lambda.Internal data StaticContext StaticContext :: Text -> Text -> Int -> Text -> Text -> StaticContext [$sel:functionName:StaticContext] :: StaticContext -> Text [$sel:functionVersion:StaticContext] :: StaticContext -> Text [$sel:functionMemorySize:StaticContext] :: StaticContext -> Int [$sel:logGroupName:StaticContext] :: StaticContext -> Text [$sel:logStreamName:StaticContext] :: StaticContext -> Text data DynamicContext DynamicContext :: Text -> Text -> Text -> UTCTime -> Maybe ClientContext -> Maybe CognitoIdentity -> DynamicContext [$sel:awsRequestId:DynamicContext] :: DynamicContext -> Text [$sel:invokedFunctionArn:DynamicContext] :: DynamicContext -> Text [$sel:xRayTraceId:DynamicContext] :: DynamicContext -> Text [$sel:deadline:DynamicContext] :: DynamicContext -> UTCTime [$sel:clientContext:DynamicContext] :: DynamicContext -> Maybe ClientContext [$sel:identity:DynamicContext] :: DynamicContext -> Maybe CognitoIdentity getStaticContext :: IO StaticContext mkContext :: StaticContext -> DynamicContext -> LambdaContext instance GHC.Generics.Generic AWS.Lambda.Internal.StaticContext instance GHC.Show.Show AWS.Lambda.Internal.StaticContext instance GHC.Show.Show AWS.Lambda.Internal.DynamicContext module AWS.Lambda.RuntimeClient.Internal eventResponseToNextData :: StaticContext -> Response Value -> (ByteString, Value, Either String LambdaContext) module AWS.Lambda.RuntimeClient data RuntimeClientConfig getRuntimeClientConfig :: IO RuntimeClientConfig getNextData :: RuntimeClientConfig -> IO (ByteString, Value, Either String LambdaContext) getNextEvent :: RuntimeClientConfig -> IO (Response Value) sendEventSuccess :: ToJSON a => RuntimeClientConfig -> ByteString -> a -> IO () sendEventError :: RuntimeClientConfig -> ByteString -> String -> IO () instance GHC.Generics.Generic AWS.Lambda.RuntimeClient.LambdaError instance GHC.Show.Show AWS.Lambda.RuntimeClient.LambdaError instance Data.Aeson.Types.ToJSON.ToJSON AWS.Lambda.RuntimeClient.LambdaError -- | These are runtimes designed for AWS Lambda, which accept a handler and -- return an application that will retreive and execute events as long as -- a container continues to exist. -- -- These runtimes expect handlers that accept a parsed JSON AST -- (Value) as the input, instead some particular type with a -- FromJSON instance. Handlers using these runtimes must take care of the -- conversion and handle errors explicitly. Handlers that should throw an -- exception or never expect to be invoked with an invalid payload, -- should simply use the runtimes in the AWS.Lambda.Runtime -- module. -- -- Each example shows the conversion from the Value type to the target -- FromJSON type. -- -- Many of these runtimes use AWS.Lambda.Combinators under the -- hood. For those interested in peeking below the abstractions provided -- here, please refer to that module. module AWS.Lambda.Runtime.Value -- | For pure functions that can never fail. -- -- Use this for simple handlers that just translate input to output -- without side-effects. -- --
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Runtime (pureRuntime)
-- import Data.Aeson (Value, FromJSON, parseJSON)
-- import Data.Aeson.Types (parseMaybe)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Value -> String
-- myHandler jsonAst =
-- case parseMaybe parseJSON jsonAst of
-- Nothing -> "My name is HAL, what's yours?"
-- Just Named { name } ->
-- "Hello, " ++ name ++ "!"
--
-- main :: IO ()
-- main = pureRuntime myHandler
--
pureRuntime :: ToJSON result => (Value -> result) -> IO ()
-- | For pure functions that can never fail that also need access to the
-- context.
--
-- Use this for simple handlers that just translate input to output
-- without side-effects, but that need the AWS Lambda Context as input.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..))
-- import AWS.Lambda.Runtime (pureRuntimeWithContext)
-- import Data.Aeson (Value, FromJSON, parseJSON)
-- import Data.Aeson.Types (parseMaybe)
-- import Data.Text (unpack)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: LambdaContext -> Value -> Either String String
-- myHandler (LambdaContext { functionName }) jsonAst =
-- case parseMaybe parseJSON jsonAst of
-- Nothing -> Right "My name is HAL, what's yours?"
-- Just Named { name } ->
-- Right $ "Hello, " ++ name ++ " from " ++ unpack functionName ++ "!"
--
-- main :: IO ()
-- main = pureRuntimeWithContext myHandler
--
pureRuntimeWithContext :: ToJSON result => (LambdaContext -> Value -> result) -> IO ()
-- | For pure functions that can still fail.
--
-- Use this for simple handlers that just translate input to output
-- without side-effects, but can fail.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Runtime (fallibleRuntime)
-- import Data.Aeson (Value, FromJSON, parseJSON)
-- import Data.Aeson.Types (parseMaybe)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Value -> Either String String
-- myHandler jsonAst =
-- case parseMaybe parseJSON jsonAst of
-- Nothing -> Right "My name is HAL, what's yours?"
-- Just Named { name } ->
-- if name == "World" then
-- Right "Hello, World!"
-- else
-- Left "Can only greet the world."
--
-- main :: IO ()
-- main = fallibleRuntime myHandler
--
fallibleRuntime :: ToJSON result => (Value -> Either String result) -> IO ()
-- | For pure functions that can still fail.
--
-- Use this for simple handlers that just translate input to output
-- without side-effects, but can fail and need the AWS Lambda Context as
-- input.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..))
-- import AWS.Lambda.Runtime (fallibleRuntimeWithContext)
-- import Data.Aeson (Value, FromJSON, parseJSON)
-- import Data.Aeson.Types (parseMaybe)
-- import Data.Text (unpack)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: LambdaContext -> Value -> Either String String
-- myHandler (LambdaContext { functionName }) jsonAst =
-- case parseMaybe parseJSON jsonAst of
-- Nothing -> Right "My name is HAL, what's yours?"
-- Just Named { name } ->
-- if name == "World" then
-- Right $ "Hello, World from " ++ unpack functionName ++ "!"
-- else
-- Left "Can only greet the world."
--
-- main :: IO ()
-- main = fallibleRuntimeWithContext myHandler
--
fallibleRuntimeWithContext :: ToJSON result => (LambdaContext -> Value -> Either String result) -> IO ()
-- | For functions with IO that can fail in a pure way (or via throw).
--
-- Use this for handlers that need any form of side-effect such as
-- reading environment variables or making network requests. However, do
-- not use this runtime if you need stateful (caching) behaviors.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Runtime (ioRuntime)
-- import Control.Monad.Trans (liftIO)
-- import Data.Aeson (Value, FromJSON, parseJSON)
-- import Data.Aeson.Types (parseMaybe)
-- import System.Environment (getEnv)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Value -> IO (Either String String)
-- myHandler jsonAst =
-- case parseMaybe parseJSON jsonAst of
-- Nothing -> return $ pure "My name is HAL, what's yours?"
-- Just Named { name } -> do
-- greeting <- liftIO $ getEnv "GREETING"
-- return $ pure $ greeting ++ name
--
-- main :: IO ()
-- main = ioRuntime myHandler
--
ioRuntime :: ToJSON result => (Value -> IO (Either String result)) -> IO ()
-- | For functions with IO that can fail in a pure way (or via throw).
--
-- Use this for handlers that need any form of side-effect such as
-- reading environment variables or making network requests, and also
-- need the AWS Lambda Context as input. However, do not use this runtime
-- if you need stateful (caching) behaviors.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..))
-- import AWS.Lambda.Runtime (ioRuntimeWithContext)
-- import Control.Monad.Trans (liftIO)
-- import Data.Aeson (Value, FromJSON, parseJSON)
-- import Data.Aeson.Types (parseMaybe)
-- import Data.Text (unpack)
-- import System.Environment (getEnv)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: LambdaContext -> Value -> IO (Either String String)
-- myHandler (LambdaContext { functionName }) jsonAst =
-- case parseMaybe parseJSON jsonAst of
-- Nothing -> return $ pure "My name is HAL, what's yours?"
-- Just Named { name } -> do
-- greeting <- liftIO $ getEnv "GREETING"
-- return $ pure $ greeting ++ name ++ " from " ++ unpack functionName ++ "!"
--
-- main :: IO ()
-- main = ioRuntimeWithContext myHandler
--
ioRuntimeWithContext :: ToJSON result => (LambdaContext -> Value -> IO (Either String result)) -> IO ()
-- | For functions that can read the lambda context and use IO within the
-- same monad.
--
-- Use this for handlers that need any form of side-effect such as
-- reading environment variables or making network requests, and prefer
-- to access the AWS Lambda Context in the same monad. However, do not
-- use this runtime if you need stateful (caching) behaviors.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..))
-- import AWS.Lambda.Runtime (readerTRuntime)
-- import Control.Monad.Reader (ReaderT, ask)
-- import Control.Monad.Trans (liftIO)
-- import Data.Aeson (Value, FromJSON, parseJSON)
-- import Data.Aeson.Types (parseMaybe)
-- import Data.Text (unpack)
-- import System.Environment (getEnv)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Value -> ReaderT LambdaContext IO String
-- myHandler jsonAst =
-- case parseMaybe parseJSON jsonAst of
-- Nothing -> return $ "My name is HAL, what's yours?"
-- Just Named { name } -> do
-- LambdaContext { functionName } <- ask
-- greeting <- liftIO $ getEnv "GREETING"
-- return $ greeting ++ name ++ " from " ++ unpack functionName ++ "!"
--
-- main :: IO ()
-- main = readerTRuntime myHandler
--
readerTRuntime :: ToJSON result => (Value -> ReaderT LambdaContext IO result) -> IO ()
-- | For any monad that supports IO and catch. Useful if
-- you need caching behaviours or are comfortable manipulating monad
-- transformers, and want full control over your monadic interface.
--
-- In a future version, this function will be renamed to
-- mRuntimeWithContext (after the deprecated function is
-- removed).
--
-- A contrived example, that parses the Value argument directly
-- instead of using the higher-level features in
-- AWS.Lambda.Runtime.Value:
--
--
-- {-# LANGUAGE DeriveAnyClass, DeriveGeneric, NamedFieldPuns #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..))
-- import AWS.Lambda.Runtime (mRuntimeWithContext')
-- import Control.Monad.Catch (Exception, throwM)
-- import Control.Monad.State.Lazy (StateT, evalStateT, get, put)
-- import Control.Monad.Trans (liftIO)
-- import Data.Aeson (FromJSON, Result(..), Value, fromJSON)
-- import Data.Text (unpack)
-- import System.Environment (getEnv)
-- import GHC.Generics (Generic)
--
-- data AesonParseException = AesonParseException String
-- deriving (Show, Exception)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: LambdaContext -> Value -> StateT Int IO String
-- myHandler LambdaContext { functionName } value = do
-- greeting <- liftIO $ getEnv "GREETING"
-- Named { name } <- case fromJSON value of
-- Error err -> throwM $ AesonParseException err
-- Success named -> pure named
-- greetingCount <- get
-- put $ greetingCount + 1
--
-- return $ greeting ++ name ++ " (" ++ show greetingCount ++ ") from " ++ unpack functionName ++ "!"
--
-- main :: IO ()
-- main = evalStateT (mRuntimeWithContext' myHandler) 0
--
mRuntimeWithContext' :: (MonadCatch m, MonadIO m, ToJSON result) => (LambdaContext -> Value -> m result) -> m ()
-- | For any monad that supports IO and catch. Useful if
-- you need caching behaviours or are comfortable manipulating monad
-- transformers, want full control over your monadic interface, but don't
-- need to inspect the LambdaContext.
--
-- A contrived example, that parses the Value argument directly
-- instead of using the higher-level features in
-- AWS.Lambda.Runtime.Value:
--
--
-- {-# LANGUAGE DeriveAnyClass, DeriveGeneric, NamedFieldPuns #-}
--
-- module Main where
--
-- import AWS.Lambda.Runtime (mRuntime)
-- import Control.Monad.Catch (Exception, throwM)
-- import Control.Monad.State.Lazy (StateT, evalStateT, get, put)
-- import Control.Monad.Trans (liftIO)
-- import Data.Aeson (FromJSON, Result(..), Value, fromJSON)
-- import System.Environment (getEnv)
-- import GHC.Generics (Generic)
--
-- data AesonParseException = AesonParseException String
-- deriving (Show, Exception)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Value -> StateT Int IO String
-- myHandler value = do
-- greeting <- liftIO $ getEnv "GREETING"
-- Named { name } <- case fromJSON value of
-- Error err -> throwM $ AesonParseException err
-- Success named -> pure named
-- greetingCount <- get
-- put $ greetingCount + 1
--
-- return $ greeting ++ name ++ " (" ++ show greetingCount ++ ")!"
--
-- main :: IO ()
-- main = evalStateT (mRuntime myHandler) 0
--
mRuntime :: (MonadCatch m, MonadIO m, ToJSON result) => (Value -> m result) -> m ()
-- | For any monad that supports IO/catch/Reader LambdaContext.
--
-- This function is problematic, and has been deprecated. The
-- HasLambdaContext constraint requires that a
-- LambdaContext is settable in the m monad, but that is
-- not the case - we only have a LambdaContext during the
-- request/response cycle.
--
-- If you need caching behavours or are comfortable manipulating monad
-- transformers and want full control over your monadic interface,
-- consider mRuntimeWithContext'.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..), runReaderTLambdaContext)
-- import AWS.Lambda.Runtime (mRuntimeWithContext)
-- import Control.Monad.Reader (ReaderT, ask)
-- import Control.Monad.State.Lazy (StateT, evalStateT, get, put)
-- import Control.Monad.Trans (liftIO)
-- import Data.Aeson (Value, FromJSON, parseJSON)
-- import Data.Aeson.Types (parseMaybe)
-- import Data.Text (unpack)
-- import System.Environment (getEnv)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Value -> StateT Int (ReaderT LambdaContext IO) String
-- myHandler jsonAst =
-- case parseMaybe parseJSON jsonAst of
-- Nothing -> return $ "My name is HAL, what's yours?"
-- Just Named { name } -> do
-- LambdaContext { functionName } <- ask
-- greeting <- liftIO $ getEnv "GREETING"
--
-- greetingCount <- get
-- put $ greetingCount + 1
--
-- return $ greeting ++ name ++ " (" ++ show greetingCount ++ ") from " ++ unpack functionName ++ "!"
--
-- main :: IO ()
-- main = runReaderTLambdaContext (evalStateT (mRuntimeWithContext myHandler) 0)
--
-- | Deprecated: mRuntimeWithContext will be replaced by
-- mRuntimeWithContext' in a future version. This type signature makes
-- impossible promises - see the haddock for details.
mRuntimeWithContext :: (HasLambdaContext r, MonadCatch m, MonadReader r m, MonadIO m, ToJSON result) => (Value -> m result) -> m ()
-- | These are runtimes designed for AWS Lambda, which accept a handler and
-- return an application that will retreive and execute events as long as
-- a container continues to exist.
--
-- Many of these runtimes use AWS.Lambda.Combinators under the
-- hood. For those interested in peeking below the abstractions provided
-- here, please refer to that module.
module AWS.Lambda.Runtime
-- | For pure functions that can never fail.
--
-- Use this for simple handlers that just translate input to output
-- without side-effects.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Runtime (pureRuntime)
-- import Data.Aeson (FromJSON)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Named -> String
-- myHandler Named { name } = "Hello, " ++ name ++ "!"
--
-- main :: IO ()
-- main = pureRuntime myHandler
--
pureRuntime :: (FromJSON event, ToJSON result) => (event -> result) -> IO ()
-- | For pure functions that can never fail that also need access to the
-- context.
--
-- Use this for simple handlers that just translate input to output
-- without side-effects, but that need the AWS Lambda Context as input.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..))
-- import AWS.Lambda.Runtime (pureRuntimeWithContext)
-- import Data.Aeson (FromJSON)
-- import Data.Text (unpack)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: LambdaContext -> Named -> String
-- myHandler (LambdaContext { functionName }) (Named { name }) =
-- "Hello, " ++ name ++ " from " ++ unpack functionName ++ "!"
--
-- main :: IO ()
-- main = pureRuntimeWithContext myHandler
--
pureRuntimeWithContext :: (FromJSON event, ToJSON result) => (LambdaContext -> event -> result) -> IO ()
-- | For pure functions that can still fail.
--
-- Use this for simple handlers that just translate input to output
-- without side-effects, but can fail.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Runtime (fallibleRuntime)
-- import Data.Aeson (FromJSON)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Named -> Either String String
-- myHandler (Named { name }) =
-- if name == "World" then
-- Right "Hello, World!"
-- else
-- Left "Can only greet the world."
--
-- main :: IO ()
-- main = fallibleRuntime myHandler
--
fallibleRuntime :: (FromJSON event, ToJSON result) => (event -> Either String result) -> IO ()
-- | For pure functions that can still fail.
--
-- Use this for simple handlers that just translate input to output
-- without side-effects, but can fail and need the AWS Lambda Context as
-- input.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..))
-- import AWS.Lambda.Runtime (fallibleRuntimeWithContext)
-- import Data.Aeson (FromJSON)
-- import Data.Text (unpack)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: LambdaContext -> Named -> Either String String
-- myHandler (LambdaContext { functionName }) (Named { name }) =
-- if name == "World" then
-- Right $ "Hello, World from " ++ unpack functionName ++ "!"
-- else
-- Left "Can only greet the world."
--
-- main :: IO ()
-- main = fallibleRuntimeWithContext myHandler
--
fallibleRuntimeWithContext :: (FromJSON event, ToJSON result) => (LambdaContext -> event -> Either String result) -> IO ()
-- | For functions with IO that can fail in a pure way (or via throw).
--
-- Use this for handlers that need any form of side-effect such as
-- reading environment variables or making network requests. However, do
-- not use this runtime if you need stateful (caching) behaviors.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Runtime (ioRuntime)
-- import Data.Aeson (FromJSON)
-- import System.Environment (getEnv)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Named -> IO (Either String String)
-- myHandler (Named { name }) = do
-- greeting <- getEnv "GREETING"
-- return $ pure $ greeting ++ name
--
-- main :: IO ()
-- main = ioRuntime myHandler
--
ioRuntime :: (FromJSON event, ToJSON result) => (event -> IO (Either String result)) -> IO ()
-- | For functions with IO that can fail in a pure way (or via throw).
--
-- Use this for handlers that need any form of side-effect such as
-- reading environment variables or making network requests, and also
-- need the AWS Lambda Context as input. However, do not use this runtime
-- if you need stateful (caching) behaviors.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..))
-- import AWS.Lambda.Runtime (ioRuntimeWithContext)
-- import Data.Aeson (FromJSON)
-- import Data.Text (unpack)
-- import System.Environment (getEnv)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: LambdaContext -> Named -> IO (Either String String)
-- myHandler (LambdaContext { functionName }) (Named { name }) = do
-- greeting <- getEnv "GREETING"
-- return $ pure $ greeting ++ name ++ " from " ++ unpack functionName ++ "!"
--
-- main :: IO ()
-- main = ioRuntimeWithContext myHandler
--
ioRuntimeWithContext :: (FromJSON event, ToJSON result) => (LambdaContext -> event -> IO (Either String result)) -> IO ()
-- | For functions that can read the lambda context and use IO within the
-- same monad.
--
-- Use this for handlers that need any form of side-effect such as
-- reading environment variables or making network requests, and prefer
-- to access the AWS Lambda Context in the same monad. However, do not
-- use this runtime if you need stateful (caching) behaviors.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..))
-- import AWS.Lambda.Runtime (readerTRuntime)
-- import Control.Monad.Reader (ReaderT, ask)
-- import Control.Monad.Trans (liftIO)
-- import Data.Aeson (FromJSON)
-- import Data.Text (unpack)
-- import System.Environment (getEnv)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Named -> ReaderT LambdaContext IO String
-- myHandler Named { name } = do
-- LambdaContext { functionName } <- ask
-- greeting <- liftIO $ getEnv "GREETING"
-- return $ greeting ++ name ++ " from " ++ unpack functionName ++ "!"
--
-- main :: IO ()
-- main = readerTRuntime myHandler
--
readerTRuntime :: (FromJSON event, ToJSON result) => (event -> ReaderT LambdaContext IO result) -> IO ()
-- | For any monad that supports IO and catch. Useful if
-- you need caching behaviours or are comfortable manipulating monad
-- transformers, and want full control over your monadic interface.
--
-- In a future version, this function will be renamed to
-- mRuntimeWithContext (after the deprecated function is
-- removed).
--
--
-- {-# LANGUAGE DeriveGeneric, NamedFieldPuns #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..))
-- import AWS.Lambda.Runtime (mRuntimeWithContext')
-- import Control.Monad.State.Lazy (StateT, evalStateT, get, put)
-- import Control.Monad.Trans (liftIO)
-- import Data.Aeson (FromJSON)
-- import Data.Text (unpack)
-- import System.Environment (getEnv)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: LambdaContext -> Named -> StateT Int IO String
-- myHandler LambdaContext { functionName } Named { name } = do
-- greeting <- liftIO $ getEnv "GREETING"
--
-- greetingCount <- get
-- put $ greetingCount + 1
--
-- return $ greeting ++ name ++ " (" ++ show greetingCount ++ ") from " ++ unpack functionName ++ "!"
--
-- main :: IO ()
-- main = evalStateT (mRuntimeWithContext' myHandler) 0
--
mRuntimeWithContext' :: (MonadCatch m, MonadIO m, FromJSON event, ToJSON result) => (LambdaContext -> event -> m result) -> m ()
-- | For any monad that supports IO and catch. Useful if
-- you need caching behaviours or are comfortable manipulating monad
-- transformers, want full control over your monadic interface, but don't
-- need to inspect the LambdaContext.
--
--
-- {-# LANGUAGE DeriveGeneric, NamedFieldPuns #-}
--
-- module Main where
--
-- import AWS.Lambda.Runtime (mRuntime)
-- import Control.Monad.State.Lazy (StateT, evalStateT, get, put)
-- import Control.Monad.Trans (liftIO)
-- import Data.Aeson (FromJSON)
-- import System.Environment (getEnv)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Named -> StateT Int IO String
-- myHandler Named { name } = do
-- greeting <- liftIO $ getEnv "GREETING"
--
-- greetingCount <- get
-- put $ greetingCount + 1
--
-- return $ greeting ++ name ++ " (" ++ show greetingCount ++ ")!"
--
-- main :: IO ()
-- main = evalStateT (mRuntime myHandler) 0
--
mRuntime :: (MonadCatch m, MonadIO m, FromJSON event, ToJSON result) => (event -> m result) -> m ()
-- | For any monad that supports IO/catch/Reader LambdaContext.
--
-- This function is problematic, and has been deprecated. The
-- HasLambdaContext constraint requires that a
-- LambdaContext is settable in the m monad, but that is
-- not the case - we only have a LambdaContext during the
-- request/response cycle.
--
-- If you need caching behavours or are comfortable manipulating monad
-- transformers and want full control over your monadic interface,
-- consider mRuntimeWithContext'.
--
--
-- {-# LANGUAGE NamedFieldPuns, DeriveGeneric #-}
--
-- module Main where
--
-- import AWS.Lambda.Context (LambdaContext(..), runReaderTLambdaContext)
-- import AWS.Lambda.Runtime (mRuntimeWithContext)
-- import Control.Monad.Reader (ReaderT, ask)
-- import Control.Monad.State.Lazy (StateT, evalStateT, get, put)
-- import Control.Monad.Trans (liftIO)
-- import Data.Aeson (FromJSON)
-- import Data.Text (unpack)
-- import System.Environment (getEnv)
-- import GHC.Generics (Generic)
--
-- data Named = Named {
-- name :: String
-- } deriving Generic
-- instance FromJSON Named
--
-- myHandler :: Named -> StateT Int (ReaderT LambdaContext IO) String
-- myHandler Named { name } = do
-- LambdaContext { functionName } <- ask
-- greeting <- liftIO $ getEnv "GREETING"
--
-- greetingCount <- get
-- put $ greetingCount + 1
--
-- return $ greeting ++ name ++ " (" ++ show greetingCount ++ ") from " ++ unpack functionName ++ "!"
--
-- main :: IO ()
-- main = runReaderTLambdaContext (evalStateT (mRuntimeWithContext myHandler) 0)
--
-- | Deprecated: mRuntimeWithContext will be replaced by
-- mRuntimeWithContext' in a future version. This type signature makes
-- impossible promises - see the haddock for details.
mRuntimeWithContext :: (HasLambdaContext r, MonadCatch m, MonadReader r m, MonadIO m, FromJSON event, ToJSON result) => (event -> m result) -> m ()