Skip to content
/ kert Public

Concise HTTP, GRPC and GraphQL library for Kotlin

License

Notifications You must be signed in to change notification settings

wsleap/kert

Folders and files

NameName
Last commit message
Last commit date

Latest commit

e2bbded · Mar 11, 2024

History

94 Commits
Apr 30, 2023
Apr 30, 2023
Mar 11, 2024
Apr 29, 2023
Apr 30, 2023
Apr 30, 2023
Jul 16, 2022
Nov 7, 2020
Nov 13, 2020
Nov 7, 2020
Apr 30, 2023
Apr 30, 2023
Apr 30, 2023
Dec 27, 2023
Apr 29, 2023
Aug 15, 2021
Apr 30, 2023
Aug 15, 2021
Aug 15, 2021

Repository files navigation

build License

Kert

Kert is a concise HTTP, GRPC and GraphQL library for Kotlin. It's not an Android library, it's a JVM library for backend development.

Compare to the official gRPC-Java, Kert provides the benefits like:

  • No need for 2 separate libraries / ports to serve HTTP and GRPC requests.
  • Simply to use HTTP health check in Kubernetes.
  • Coroutine / Flow based interface more intuitive for async processing and context propagation.
  • Simple filter & interceptor interface for async handling.

Server Example:

val server = httpServer(8080) {
  // http filter
  filter { req, next ->
    println("Serving request ${req.path}")
    next(req)
  }

  // http service
  router {
    // http request handler
    get("/ping") {
      response(body = "pong")
    }
  }

  // grpc service
  grpc {
    // enable server reflection
    serverReflection = true

    // grpc interceptor
    interceptor( object : GrpcInterceptor {
      override suspend fun <REQ, RESP> invoke(method: MethodDescriptor<REQ, RESP>, req: GrpcRequest<REQ>, next: GrpcHandler<REQ, RESP>): GrpcResponse<RESP> {
        // intercept the request
        if (req.metadata["authentication"] == null) throw IllegalArgumentException("Authentication header is missing")

        // intercept each message in the streaming request
        val filteredReq = req.copy(messages = req.messages.map {
          println(it)
          it
        })
        return next(method, filteredReq)
      }
    })

    // register service implementation
    service(EchoServiceImpl())
  }

  // GraphQL
  graphql {
    playground = true

    schema {
      config {
        supportedPackages = listOf("<your package name>")
      }
      query(MyExampleQuery())
    }
  }
}

server.start()

Client Example:

// http request
val client = httpClient {
  options {
    defaultHost = "localhost"
    defaultPort = 8551
    protocolVersion = HttpVersion.HTTP_2
  }

  // a client side filter to set authorization header in request
  filter { req, next ->
    req.headers["authorization"] = "my-authorization-header"
    next(req)
  }
}
client.get("ping")

// grpc request
val stub = EchoGrpcKt.stub(client)
stub.unary(EchoReq.newBuilder().setId(1).setValue("hello").build())