Copyright | (c) Nike Inc. 2018 |
---|---|
License | BSD3 |
Maintainer | nathan.fairhurst@nike.com, fernando.freire@nike.com |
Stability | stable |
Safe Haskell | None |
Language | Haskell2010 |
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.
Synopsis
- pureRuntime :: (FromJSON event, ToJSON result) => (event -> result) -> IO ()
- pureRuntimeWithContext :: (FromJSON event, ToJSON result) => (LambdaContext -> event -> result) -> IO ()
- fallibleRuntime :: (FromJSON event, ToJSON result) => (event -> Either String result) -> IO ()
- fallibleRuntimeWithContext :: (FromJSON event, ToJSON result) => (LambdaContext -> event -> Either String result) -> IO ()
- ioRuntime :: (FromJSON event, ToJSON result) => (event -> IO (Either String result)) -> IO ()
- ioRuntimeWithContext :: (FromJSON event, ToJSON result) => (LambdaContext -> event -> IO (Either String result)) -> IO ()
- readerTRuntime :: (FromJSON event, ToJSON result) => (event -> ReaderT LambdaContext IO result) -> IO ()
- mRuntimeWithContext' :: (MonadCatch m, MonadIO m, FromJSON event, ToJSON result) => (LambdaContext -> event -> m result) -> m ()
- mRuntime :: (MonadCatch m, MonadIO m, FromJSON event, ToJSON result) => (event -> m result) -> m ()
- mRuntimeWithContext :: (HasLambdaContext r, MonadCatch m, MonadReader r m, MonadIO m, FromJSON event, ToJSON result) => (event -> m result) -> m ()
Documentation
pureRuntime :: (FromJSON event, ToJSON result) => (event -> result) -> IO () Source #
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
pureRuntimeWithContext :: (FromJSON event, ToJSON result) => (LambdaContext -> event -> result) -> IO () Source #
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
fallibleRuntime :: (FromJSON event, ToJSON result) => (event -> Either String result) -> IO () Source #
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
fallibleRuntimeWithContext :: (FromJSON event, ToJSON result) => (LambdaContext -> event -> Either String result) -> IO () Source #
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
ioRuntime :: (FromJSON event, ToJSON result) => (event -> IO (Either String result)) -> IO () Source #
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
ioRuntimeWithContext :: (FromJSON event, ToJSON result) => (LambdaContext -> event -> IO (Either String result)) -> IO () Source #
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
readerTRuntime :: (FromJSON event, ToJSON result) => (event -> ReaderT LambdaContext IO result) -> IO () Source #
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
mRuntimeWithContext' :: (MonadCatch m, MonadIO m, FromJSON event, ToJSON result) => (LambdaContext -> event -> m result) -> m () Source #
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
mRuntime :: (MonadCatch m, MonadIO m, FromJSON event, ToJSON result) => (event -> m result) -> m () Source #
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
mRuntimeWithContext :: (HasLambdaContext r, MonadCatch m, MonadReader r m, MonadIO m, FromJSON event, ToJSON result) => (event -> m result) -> m () Source #
Deprecated: mRuntimeWithContext will be replaced by mRuntimeWithContext' in a future version. This type signature makes impossible promises - see the haddock for details.
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)