Upgrade to Pro — share decks privately, control downloads, hide ads and more …

GRPC Services in Kong

GRPC Services in Kong

This document is the base for my presentation about the Kong Gateway and its usages with the gRPC plugins. The Kong gateway provides two kinds of plugins that are very crucial when thinking about working with gRPC services. There is a grpc gateway plugin and a grpc web plugin. How to work with them and how to configure them isn't difficult but some help is always good. I provide with this presentation a general look on gRPC itself and how to manage that using an API gateway.

More Decks by João Filipe Sabino Esperancinha

Other Decks in Programming

Transcript

  1. Summary - gRPC theory - What is it? - What

    are the benefits? - What are the drawbacks? - Making a gRPC service in the backend in Kotlin - Making a gRPC client to communicate with the backend in Kotlin - Creating a gRPC-web client for the front end in Javascript - Using the gRPC gateway plugin - Using the gRPC web plugin - Conclusion
  2. About me João Esperancinha • Java • Kotlin • Groovy

    • Scala • Software Engineer 10+ years • JESPROTECH owner for 1 year Kong Champion/Java Professional/Spring Professional
  3. gRPC General Remote Procedure Call Modern open source network protocol

    that allows invocations of functions and or procedures in the remote machine as if they were executed locally. The result of the function is returned as if the call was made locally. This is what RPC means. General, in this context , turns RPC into gRPC and it means that gRPC can be generically used in different frameworks and platforms Theory
  4. How is this made generic? Protobuffer files! syntax = "proto3";

    package org.jesperancinha.wlsm.messenger; service Messenger { rpc Send (Message) returns (MessageResponse); } message Message { string text = 1; string author = 2; } message MessageResponse { int32 result = 1; } • Language Agnostic • Platform neutral • Binary serialization • Own Language
  5. gRPC backend services start out as protobuf files. The word

    protobuf means Protocol Buffer and it essentially means what it actually does. This is the data structure format used in the buffers created to transmit data. Backend Service
  6. How to generate protobuf { protoc { artifact = libs.protoc.asProvider().get().toString()

    } plugins { create("grpc") { artifact = libs.protoc.gen.grpc.java.get().toString() } create("grpckt") { artifact = libs.protoc.gen.grpc.kotlin.get().toString() + ":jdk8@jar" } } generateProtoTasks { all().forEach { it.plugins { create("grpc") create("grpckt") } it.builtins { create("kotlin") } } } } gradle.kts
  7. MessengerService syntax = "proto3"; package org.jesperancinha.wlsm.messenger; service Messenger { rpc

    Send (Message) returns (MessageResponse); } message Message { string text = 1; string author = 2; } message MessageResponse { int32 result = 1; } Proto3 Syntax Request Message Response Message Package RPC Protocol
  8. MessengerService public abstract class MessengerCoroutineImplBase( coroutineContext: CoroutineContext = EmptyCoroutineContext, )

    : AbstractCoroutineServerImpl(coroutineContext) { public open suspend fun send(request: MessengerOuterClass.Message): MessengerOuterClass.MessageResponse = throw StatusException(UNIMPLEMENTED.withDescription("Method org.jesperancinha.wlsm.messenger.Messenger.Send is unimplemented")) final override fun bindService(): ServerServiceDefinition = builder(getServiceDescriptor()) .addMethod(unaryServerMethodDefinition( context = this.context, descriptor = MessengerGrpc.getSendMethod(), implementation = ::send )).build() } }
  9. MessengerService internal class MessengerService : MessengerGrpcKt.MessengerCoroutineImplBase() { override suspend fun

    send(request: MessengerOuterClass.Message) = messageResponse { println(request) this.result = 0 } } Generated by proto
  10. MessengerService class MessengerServer(private val port: Int) { val server: Server

    = ServerBuilder .forPort(port) .addService(MessengerService()) .build() fun start() { server.start() println("Server started, listening on $port") Runtime.getRuntime().addShutdownHook( Thread { println("*** shutting down gRPC server since JVM is shutting down") [email protected]() println("*** server shut down") }, ) }
  11. Just as the gRPC services, the client files get also

    generated with the protobuf plugin. Once that is created, we can easily use the client to access the service. Client
  12. MessengerService - client @StubFor(MessengerGrpc::class) public class MessengerCoroutineStub @JvmOverloads constructor( channel:

    Channel, callOptions: CallOptions = DEFAULT, ) : AbstractCoroutineStub<MessengerCoroutineStub>(channel, callOptions) { override fun build(channel: Channel, callOptions: CallOptions): MessengerCoroutineStub = MessengerCoroutineStub(channel, callOptions) public suspend fun send(request: MessengerOuterClass.Message, headers: Metadata = Metadata()): MessengerOuterClass.MessageResponse = unaryRpc( channel, MessengerGrpc.getSendMethod(), request, callOptions, headers )
  13. MessengerService - client class MessengerClient(private val channel: ManagedChannel) : Closeable

    { private val stub: MessengerCoroutineStub = MessengerCoroutineStub(channel) suspend fun sendMessage(text: String, author: String) { val request = message { this.text = text this.author = author } val response = stub.send(request) println("Received: ${response.result}") } override fun close() { channel.shutdown().awaitTermination(5, TimeUnit.SECONDS) } } Generated by proto
  14. Where and how do we make the tests? How do

    we connect Kong KONNECT to our containerized environment? How do we see gRPC in action? How to use docker-compose
  15. Direct connection via gRPC Connection to gRPC service via JSON

    requests Connection to the gRPC service via web requests (all requests made from a browser) Kong Konnect Goals
  16. Conclusions • Use HTTP/HTTPS requests For both plugins • Translate

    requests to gRPC • Need a protobuf (.proto) file • Service configured with gRPC and a Route with HTTP/HTTPS
  17. Conclusions • JSON to gRPC conversion For the gateway plugin

    For the web plugin • gRPC-web to gRPC Direct gRPC • Both Service and Path need to be configured for gRPC
  18. • Source Repository ◦ https://github.com/jesperancinha/wild-life-safety-monitor Use git clone from the

    command prompt to download the full code base: > git clone https://github.com/jesperancinha/wild-life-safety-monitor.git You’ll be prompted for a username and password which should be your github account. The easy way: > make b > make run The manual way: > gradle build > ./gradlew run Project Location
  19. Resources: • https://kodekloud.com/blog/grpc/ • https://docs.konghq.com/hub/kong-inc/grpc-gateway/ • https://grpc-ecosystem.github.io/grpc-gateway/ • https://github.com/protocolbuffers/protobuf •

    https://konghq.com/blog/engineering/manage-grpc-services-kong • https://grpc.io/docs/languages/kotlin/quickstart/ • https://docs.gradle.org/current/userguide/platforms.html#sub:version-catalog • https://docs.konghq.com/hub/kong-inc/grpc-web/ • https://github.com/grpc/grpc-web/tree/master/net/grpc/gateway/examples/helloworld
  20. About me • Homepage - https://joaofilipesabinoesperancinha.nl • LinkedIn - https://www.linkedin.com/in/joaoesperancinha/

    • YouTube - JESPROTECH ▪ https://www.youtube.com/channel/UCzS_JK7QsZ7ZH-zTc5kBX_g ▪ https://www.youtube.com/@jesprotech • Bluesky - https://bsky.app/profile/jesperancinha.bsky.social • Mastodon - https://masto.ai/@jesperancinha • GitHub - https://github.com/jesperancinha • Hackernoon - https://hackernoon.com/u/jesperancinha • DevTO - https://dev.to/jofisaes • Medium - https://medium.com/@jofisaes