Skip to content

Commit

Permalink
Add README and rename ZLambdaApp to ZLambda (#82)
Browse files Browse the repository at this point in the history
  • Loading branch information
jrmsamson authored Feb 24, 2022
1 parent a157cb1 commit c7d901c
Show file tree
Hide file tree
Showing 9 changed files with 67 additions and 52 deletions.
44 changes: 44 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,47 @@

[Badge-Discord]: https://img.shields.io/discord/629491597070827530?logo=discord "chat on discord"
[Link-Discord]: https://discord.gg/a37AwDkyvC "Discord"

# Overview

A ZIO-based AWS Custom Runtime compatible with GraalVM Native Image.

# Installation


```scala
libraryDependencies += "dev.zio" %% "zio-lambda" % "1.0.0-RC1"
```

### Optional dependencies
```scala
libraryDependencies += "dev.zio" %% "zio-lambda-event" % "1.0.0-RC1"

libraryDependencies += "dev.zio" %% "zio-lambda-response" % "1.0.0-RC1"
```

# Usage

Create your Lambda function by extending ZLambda

```scala
import zio.Console._
import zio._
import zio.lambda._

object SimpleHandler extends ZLambda[KinesisEvent, String] {

override def apply(event: KinesisEvent, context: Context): RIO[ZEnv, String] =
for {
_ <- printLine(event.message)
} yield "Handler ran successfully"
}
```
zio-lambda depends on [**zio-json**](https://github.com/zio/zio-json) for decoding any event you send to it and enconding any response you send back to the Lambda service.
You can either create your own data types or use the ones that are included in **zio-lambda-event** and **zio-lambda-response**.

The last step is to define the way your function will be invoked. There are two ways:

* Upload zio-lambda as a [Lambda Layer](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html) (Each release will contain a zip file ready to be used as a lambda layer) and your function.

* Include zio-lambda in your function's deployment package in the form of an executable file named **bootstrap** by using [GraalVM Native Image](https://www.graalvm.org/22.0/reference-manual/native-image/)
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
package zio.lambda.example

import zio._
import zio.Console._
import zio.lambda.Context
import zio.lambda.ZLambdaApp
import zio._
import zio.lambda._

object SimpleHandler extends ZLambdaApp[CustomEvent, CustomResponse] {
object SimpleHandler extends ZLambda[CustomEvent, String] {

override def apply(event: CustomEvent, context: Context): RIO[ZEnv, CustomResponse] =
override def apply(event: CustomEvent, context: Context): RIO[ZEnv, String] =
for {
_ <- printLine(event.message)
} yield CustomResponse("Handler ran successfully")
} yield "Handler ran successfully"

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,36 +6,7 @@ import zio.lambda.internal.LambdaEnvironment
import zio.lambda.internal.LoopProcessor
import zio.lambda.internal.RuntimeApiLive

/**
* Class to be extended by the Lambda function.
*
* Implementation example:
*
* {{{
* object MyLambda extends ZLambda[MyPayload, MyResponse] {
* def handle(request: MyPayload): ZIO[ZEnv, Throwable, MyResponse] = ???
* }
*
* final case class MyPayload(value: String)
*
* object MyPayload {
* import zio.json.JsonDecoder
* import zio.json.DeriveJsonDecoder
*
* implicit val jsonDecoder: JsonDecoder[MyPayload] = DeriveJsonDecoder.gen
* }
*
* final case class MyResponse(value: String)
*
* object MyResponse {
* import zio.json.JsonEncoder
* import zio.json.DeriveJsonEncoder
*
* implicit val jsonEncoder: JsonEncoder[MyResponse] = DeriveJsonEncoder.gen
* }
* }}}
*/
abstract class ZLambdaApp[E, A](
abstract class ZLambda[E, A](
implicit val lambdaEventDecoder: JsonDecoder[E],
implicit val lambdaResponseEncoder: JsonEncoder[A]
) extends ZIOAppDefault { self =>
Expand Down
6 changes: 3 additions & 3 deletions lambda/src/main/scala/zio/lambda/internal/LambdaLoader.scala
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
package zio.lambda.internal

import zio._
import zio.lambda.ZLambdaApp
import zio.lambda.ZLambda

trait LambdaLoader {
def loadLambda: UIO[Either[Throwable, ZLambdaApp[_, _]]]
def loadLambda: UIO[Either[Throwable, ZLambda[_, _]]]
}

object LambdaLoader {
def loadLambda: URIO[LambdaLoader, Either[Throwable, ZLambdaApp[_, _]]] =
def loadLambda: URIO[LambdaLoader, Either[Throwable, ZLambda[_, _]]] =
ZIO.serviceWithZIO(_.loadLambda)
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
package zio.lambda.internal

import zio._
import zio.lambda.ZLambdaApp
import zio.lambda.ZLambda

final case class LambdaLoaderLive(
customClassLoader: CustomClassLoader,
environment: LambdaEnvironment
) extends LambdaLoader {

override lazy val loadLambda: UIO[Either[Throwable, ZLambdaApp[_, _]]] =
override lazy val loadLambda: UIO[Either[Throwable, ZLambda[_, _]]] =
customClassLoader.getClassLoader
.flatMap[Any, Throwable, ZLambdaApp[_, _]](classLoader =>
.flatMap[Any, Throwable, ZLambda[_, _]](classLoader =>
ZIO
.attempt(
Class
Expand All @@ -21,7 +21,7 @@ final case class LambdaLoaderLive(
)
.getDeclaredField("MODULE$")
.get(null)
.asInstanceOf[ZLambdaApp[_, _]]
.asInstanceOf[ZLambda[_, _]]
)
.refineOrDie { case ex: ClassNotFoundException => ex }
)
Expand Down
9 changes: 4 additions & 5 deletions lambda/src/main/scala/zio/lambda/internal/LoopProcessor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,16 @@ package zio.lambda.internal

import zio._
import zio.lambda.Context
import zio.lambda.ZLambdaApp
import zio.lambda.ZLambda

trait LoopProcessor {
def loop(eitherZLambda: Either[Throwable, ZLambdaApp[_, _]]): RIO[ZEnv, Unit]
def loop(eitherZLambda: Either[Throwable, ZLambda[_, _]]): RIO[ZEnv, Unit]
}

object LoopProcessor {

final case class Live(runtimeApi: RuntimeApi, environment: LambdaEnvironment) extends LoopProcessor {
def loop(eitherZLambda: Either[Throwable, ZLambdaApp[_, _]]): RIO[ZEnv, Unit] =
def loop(eitherZLambda: Either[Throwable, ZLambda[_, _]]): RIO[ZEnv, Unit] =
eitherZLambda match {
case Right(zLambda) =>
runtimeApi.getNextInvocation
Expand All @@ -29,7 +29,6 @@ object LoopProcessor {
)
)
)
.tapError(throwable => ZIO.attempt(println(s"Error=$throwable")))
.forever

case Left(throwable) =>
Expand All @@ -47,7 +46,7 @@ object LoopProcessor {
}

def loop(
eitherZLambda: Either[Throwable, ZLambdaApp[_, _]]
eitherZLambda: Either[Throwable, ZLambda[_, _]]
): RIO[LoopProcessor with ZEnv, Unit] =
ZIO.serviceWithZIO[LoopProcessor](_.loop(eitherZLambda))

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ final case class RuntimeApiLive(environment: LambdaEnvironment) extends RuntimeA
ZIO.attempt {
val con = nextInvocationUrl.openConnection().asInstanceOf[HttpURLConnection]
con.setRequestMethod("GET")
con.setConnectTimeout(0)
con.setReadTimeout(0)
val responseBody = readResponse(con.getInputStream())
InvocationRequest.fromHttpResponse(con.getHeaderFields(), responseBody)
}
Expand Down
6 changes: 3 additions & 3 deletions lambda/src/test/scala/zio/lambda/internal/TestZLambda.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package zio.lambda.internal

import zio._
import zio.json._
import zio.lambda.ZLambdaApp
import zio.lambda.ZLambda
import zio.lambda.Context

final case class CustomPayload(value: String)
Expand All @@ -16,12 +16,12 @@ object CustomResponse {
implicit val encoder: JsonEncoder[CustomResponse] = DeriveJsonEncoder.gen[CustomResponse]
}

object SuccessZLambda extends ZLambdaApp[CustomPayload, CustomResponse] {
object SuccessZLambda extends ZLambda[CustomPayload, CustomResponse] {
override def apply(event: CustomPayload, context: Context): RIO[ZEnv, CustomResponse] =
ZIO.succeed(CustomResponse(event.value))
}

object ErrorZLambda extends ZLambdaApp[CustomPayload, CustomResponse] {
object ErrorZLambda extends ZLambda[CustomPayload, CustomResponse] {
override def apply(event: CustomPayload, context: Context): RIO[ZEnv, CustomResponse] =
ZIO.fail(new Throwable("ZLambda error"))
}
2 changes: 1 addition & 1 deletion project/plugins.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ addSbtPlugin("pl.project13.scala" % "sbt-jmh" % "0.4.3")
addSbtPlugin("com.eed3si9n" % "sbt-buildinfo" % "0.11.0")
addSbtPlugin("org.scoverage" % "sbt-scoverage" % "1.9.3")
addSbtPlugin("org.scalameta" % "sbt-mdoc" % "2.3.0")
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1032048a")
addSbtPlugin("ch.epfl.scala" % "sbt-bloop" % "1.4.13")
addSbtPlugin("com.eed3si9n" % "sbt-unidoc" % "0.4.3")
addSbtPlugin("com.github.sbt" % "sbt-ci-release" % "1.5.10")
addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.6")
Expand Down

0 comments on commit c7d901c

Please sign in to comment.