 Okay, so hello everyone. My name is Martin Kova and I work as a software engineer at Redhead and I spent the last few years working on Quarkus. So today I'm going to talk about Quarkus and GRPC. First I'd like to give you a short introduction to these technologies but it should be really just a very briefly brief description and then we'll create our first demo application and then run our application into development mode and show some of the cool features we provide in Quarkus. So, okay, we only have 20 minutes so we should probably stop. What is Quarkus? So, you can find a lot of talks and presentations about Quarkus involved. Those presentations usually start with supersonic subatomic Java description. I prefer the following two sentences when I try to introduce Quarkus to Java developers. So first of all, it's a build time oriented Java stack. The fact that it's build time basically means that most of the magic happens when you build your application. And we call it Java stack, not Java framework or anything like that because it's basically a set of tools and APIs and runtime bits. So it's kind of hard to define. And the other sentence is that it's crafted from the best of breed libraries and standards which basically means that we don't always try to reinvent the wheel but instead we use existing libraries and APIs and so on so that users don't have to learn the new stuff. So as an example, we use CI API, we use Jaxer as hibernate and a lot of other libraries. This of course sometimes challenging because not all the libraries are ready for the, let's say, build time oriented world. So we believe it's worth the effort because the fact that we use this or we try to do the build time stuff means that we can provide you an application that's really fast to start up and in terms of memory consumption. So this is the last slide I have above Quarkus as a comparison of traditional, sorry, runtime framework and Quarkus. So as you can see, usually a library when it does some magic or I call it magic but it basically means that it has to use some discovery and for example read descriptor files, read annotations on your classes, build some component model and so on. Usual runtime frameworks do this when the application starts. On the other hand, Quarkus attempts to do as much as possible during the build which basically means that we can start your application instantly and we can also throw away a lot of stuff that is not needed anymore because for example, if we need to parse an XML file, we do this when your application is being built and then we can throw away all the classes that are unnecessary. So that's all about Quarkus but what is GRPC? Well, GRPC is an open source project. It was originally invented by Google and it's a high performance RPC framework where RPC stands for remote procedural. So you can think of it as an alternative to, for example, REST APIs. But the target or the goal of this technology is to be more efficient and more performant. It works with many languages including Java. It's a contract-first technology that's really important because it basically means that before you start exposing some services or consuming services, you need to define or load the contract and the contract is in GRPC defined via protocol buffers, which is, again, a Google technology. And it provides a syntax to define the services but also it defines the way that your messages are serialized and serialized. An important thing is that this format is binary, which means that you can't use, for example, text editor to inspect your messages that are sent over the line. And it's also built on top of HTTP tool, which is another important thing to know because, of course, again, you will not be able to use the tools that are, for example, that you, for example, use when developing REST in points. And it supports unary requests, which is the traditional classical request response style of communication, but also streaming. And we're talking about client-sites, streaming, server-side, and even bi-directional streaming. And we'll show the server-side example in our demo. So there was just a very brief introduction to those technologies and then we have the demo time. So here are two links. The first one is a link that points to the repository, which contains the final version of the application, basically the result of our demo today. But we are going to use the second link, which points to code QuarkOS.io. This is a very simple web generator for project skeletons. And we are going to generate a skeleton that will use GRPC extension. So I'm checking out this GRPC extension here. At the top of the page, you can define some basic configuration of your application. So I'm going to use a different idea from 2021. I'm using Maven and starter code is included, which means that some of those extensions contain some example code that can be evolved in time. So I'm going to use the starter code and GRPC extension. You can notice that it's labeled as experimental here, which basically means that the API is not considered stable in terms of it could evolve in time in future versions of QuarkOS. But you should not be afraid of this, because first of all, it does not necessarily mean that the extension is not production ready. And we also have migration nodes for every minor and major version. So you can just migrate your application easily. So right now I can hit the generate application button and download the zip and open this in my ID. But I'm going to save some time. I already have it imported in my ID. As you can see, it's a very standard Maven application. We have some Pormex ML Maven wrapper that I'm not using, but standard source main, Java, etc. As I said before, GRPC is a contract based or contract first technology. So we use protocols or it's a standard way of GRPC to define the services. So in this code start, we have a very simple protocol that is located in source main prototype directory. Open it. As you can see, it's a simple text file. This syntax is quite self-describing. Here we have a service which is called HelloGRPC and it declares one method is named say hello, accepting hello request and returning hello reply. So this is the simplest possible type of operation, so-called unary operation. We'll add a server-side streaming executor later. Okay, so we have a protocol. It's nice, but in order to be able to work with this contract, we need some Java classes, right? So it's important to know that some of those Java sources are generated automatically for you, so you don't have to do that thing. These classes are located in the target generated sources GRPC directory. Some of these classes are Guaku specific, but most of them are just regular stops generated from the library which is called GRPC Java, the official one. If we look at the source, it's not very nice. It likes some commands and so on, but fortunately, you won't have to use most of the methods here. What I'd like to show you is this one, which is much more simple, right? This is a Guaku specific bit. It's something we call service interface, and it basically reflects the service definition that is declared in the protocol. So here for every service, we define some interface. In this case, it's called Herald GRPC because our service is called Herald GRPC. And we have a method here, say hello, which accepts the hello request, and it returns a unit hello reply. So you might wonder why you need what it actually is. Well, GRPC is by nature asynchronous and unit is an asynchronous type. It's coming from Mutant in a library, which is a reactive programming model we use in Parkus. It's based on reactive streams, but it has its own navigable API, that will show the light row. Okay, so we have this service interface that is generated, but now what? We should probably show some application code, the code that contains the business logic. So it's actually very simple. This is our service implementation. So it's a pojo. It's a normal class that implements our interface, our service interface, and it's annotated with a special annotation at the GRPC service. This annotation basically allows Krakus to discover all the services that should be registered automatically. And then we have the implementation, which is really simple in this case because it's a basic hello world example. So we just create the asynchronous type from a string value, and we use the generated hello reply class, which is that class generated by a GRPC jar. Okay, so this is a very simple implementation, but now how do I actually test whether it works or not? So like I said, protocol buffers is a binary format and it GRPC runs on top of HTTP too. So it's not so easy to use on the test, but fortunately we have something in Krakus, which is called development mode, where you basically run your application in a special mode that allows cool features, such as life reload, where you can basically change your classes and all your changes are immediately visible in your application. And this development mode also includes something we call FUI. So FUI is basically a very simple web app that is part of your application when you're in the development mode, and extensions can contribute some functionalities here. In our case, we are looking for the GRPC extension, which can list all the services we have here, and we can even test our GRPC service. As you can see, we are using JSON, specify the messages, and underneath there is some magic that transforms the JSON automatically to protocol buff types. Okay, so we have this say hello, let's test it, and it seems that it works because we sent the name FU, and the response was hello FU. So if you look at the implementation, it's probably okay, right? One nice thing is the nice feature of the development mode is the life reload. So just to demonstrate how it works, I can modify my class, save the change, and switch back to my development console, the FUI, and just reload it. And if I send the message again, I can see immediately that the result is not hello FU, but hi FU. And what happens is actually that our project is detected that you changed the class, and it reloaded the application or restarted the application for you. So this how life reload works. Okay, so the development mode is nice, but sooner or later you'll probably need some way of testing your application or services in an automated way. So of course, you can write the test, we have one generated here. It's a regular GME 5 test, except that it's validated with this annotation at Coarcus test, which basically binds a special or GME extension that starts Coarcus underneath. And this test can also inject beans and other components from the application. So in this case, we are injecting hello GRPC service interface again, but this time it's not the service that we implemented, but actually it's something that is automatically configured for you so that you can call GRPC services. And in this case, because it's test, it's even also configured so that you don't have to provide anything like host or port or anything. So we just inject our service that was implemented by our class, and then we can simply call the method here. And the generated client under the hood will basically send the message to our service, and we can then start the reply, which is pretty simple. Now, you can use the usual ways of running this test, for example, maybe Shufire from Commonline, your IDE, whatever. But there is another neat feature we have in the DEV UI, sorry, in the DEV OpenMode, and it can be started from the DEV UI, which is called continuous testing. And it basically means that when you enable it, it's disabled by default, I have just enabled it. If you enable it, then all the tests are run in the background. And afterwards, whenever you change a class that is somehow involved in your test, we run the test whenever you change the calls. In this case, we run the test and then we have something, a message in the test field. So we can take a look at what happened actually, and it says, okay, we expected a whole new, but it was high new, which is kind of expected because as you remember, we changed the message to high previously. So I can now change it back to hello, hello, sorry, save the class. And now if I reload my UI, because it's sometimes it's a bit complicated, I can see that all the tests are in our past. And I can see that, okay, my test was executed automatically because it detected that the class was changed. And everything is okay. Okay, so we have the test, we showed the continuous testing and the UI. Now it's probably time to add some more stuff. So we're going to add a server side streaming example. I'm going to create two more message types, number request, which we'll have and number reply because I want to add a new method that actually returns some random numbers and it will return them in stream. So this should be cal. Let's say we have reply that contains index and the actual value. Now let's add this method. So it's a RPC method. Let's say it's stream random numbers, sets number request and returns reply. So there's one more thing I need to add because we said they want to produce stream. So I'm just to use a keyword stream. So this keyword basically means that when we receive the number request, we will produce stream of number replies. So we changed our protocol because it's a contract for us technology. Now I need to refresh my project because I need to generate the appropriate sources for my new method operation. Now I can take a look at my, sorry, takes a little time. Okay. I can take a look at my implementation service and now it says that my interface changed because we have a new method here. In this case it is using an asynchronous type. It's called multi. And it basically means that we are returning a stream of number replies. So I'm going to implement this method. I said I want to produce some random numbers. So I'm going to just use the random calls from JDK. And now I am creating a multi. So I need to create a stream. Go create it from text. Text means that I want to produce a new message every, in this case, for example, every second. And when I create a big whole method, for everything, sorry, for everything, we're going to produce a new number, random number. So we're going to use the builder from number, people I, new builder, set index. Index means that which, which random number we produce. So I'm going to use this plus one because it starts from zero and set the value, which is the random next zero. Let's say one numbers from one to 100. And we need to add one more thing because we only want, we only want to it's like the first n requests. So I just use a pound. Let's limit it so that it's more readable. Okay, so we basically say every second create a number reply and the value is the random number we produce. So I'm going to save these clouds and everything should be ready now. So I'm going to go back to my data UI, to my services. Hello, GRPC now requires two, two operations and a new one has is streaming, server-side streaming. Okay. And I can test it. So I'm going to specify the count to two so that two random numbers are generated. So send it and it seems to work. Cool. Now, we also have a test prepared for this. So I can comment this one because I'm prepared so we can take some time. And the nice thing is that when I add the test and continuous testing is enabled, I can immediately see whether my test failed or passed. Okay. So that's it. That's all I have today. Of course, if there are any questions, feel free to ask. And also Quarkus is an open source. So feel free to contribute. Here are the pages we have Quarkus.io website. There is a Twitter handle and a web chat that is used for communication with community. Thanks, Martin. Thanks for this wonderful session. Any questions for Martin? No questions. Yeah. Okay. All right. Thanks, Martin, once again. You're welcome.