 Maybe. Hey, Clément, what do you have for us today? Today, I'm going to talk about developer experience and how Quarkus make you as a developer really feel like a superhero and going in 30 minutes from really creating a project from scratch to deploying to OpenShift. Ooh, let's see it. Everybody's trying OpenShift today, so. And I'll share the links. Please join us on the workshops while Clément is presenting Quarkus. All right, so thank you for attending this session. My name is Clément. I'm working at Red Hat. I'm doing a lot of Quarkus, a lot of reactive things. But today, we are going to talk a little bit about reactive, but it's not really the topic of this talk. Today, I'm going to explain to you how you can become a superhero. And it's all about developer experience. And Adrian Trenaman defined developer experience with this sentence, developer experience is about reducing engineering frictions between an idea and getting it in production. And I love this definition because it's about removing whole small hurdle, whole small blocker you have that will slow down your progression. When you have an idea as a developer, you really, really want to see it in live. And that's what Quarkus allow you to do. But first, what is Quarkus? Well, Quarkus is an open source tag to write Java application. It has been tailored for the cloud for microservices and serverless, but it's much more than this. Actually, Quarkus is a stack to build distributed systems because today, most of the applications we build are distributed systems. Call them microservices, monoliths, serverless, whatever, there are all distributed systems. Even games, mobile application, and most of the CLIs are distributed systems. So Quarkus provide a lot of things to build these distributed systems, going from REST to Kafka to even driven architectures to monoliths to CDC if you want to handle data and so on. We are not going to see everything today, but we are going to have a peek to a few of these domains. So Quarkus takes a very different approach to really build distributed systems the right way, building things for the cloud or for containers. The thing is Java is not necessarily cloud native. In the sense that the plain old Java style, you have your application, you do Maven package, and you get a Fadjar, a Warf file, a ER file, and you deploy it. And then it will start locating configuration file, passing them, it might be XML, so you need an XML parser. Then we will do annotation scanning, so class path scanning. We are going to look at all the classes you have in all those jobs that you have embedded because they may have annotations. We are generally also doing some class loading check, like, oh, is this class there or not? And things like that and enable a usable feature for this. And then for each framework, we are building this configuration. And finally, we are going to do something interesting for you as a user, so starting the thread, starting the server, thread pools, and so on. Quarkus is exactly the same, except that we do this before, at build time. At build time, we are going to read the configuration. We are doing the class path scanning at build time. We are going for each framework, building the models, the configuration, and we are going to infuse these inside the artifacts, which means that when we start it, we have exactly the right set of instructions to start all your frameworks. As a result, we need a lot less time to start doing the right thing, so threads, servers, and so on. But we also reduce the memory consumption. Why? Because all the classes that are only required for starting the applications are not embedded at one time anymore. So with this, we decrease startup time, decrease memory consumption, we start becoming a lot more clone native. But it's not only this. Quarkus can let you, based on this, can let you build a native executable. This is really a side effect of this build time idea. Because during this pipeline, we collect enough information about your applications so we can, well, tailor the native executable to be really, really optimized. While using Grail VM and the Grail VM compiler, as any serious compiler needs at least 25 arguments to get something right. But here in Quarkus, we make it very, very easy because we know everything about your application, dependencies, and so on. And we are going to tune this command line for having a rarely optimized native executable. We don't want fallbacks or shortcuts who really want something optimized. Then you get even faster startup, even lower memory. But yeah, this is a blue wheel. But you may wonder about the pink wheel here because there is a second ingredient in our secret source in Quarkus. And the second one is a reactive core. Remember, Quarkus is about distributed systems. And at the core of distributed systems, there is IOS, right? And we need to handle this IOS the right way in an efficient manner. Or, well, all your systems won't fly, won't scale. We'll have plenty of failures and things like that. So bad user experience at the end. So Quarkus is based on a reactive core and then a set of extension and finally your application code. So what's wrong with the traditional model? The traditional model associates requests to worker thread, which means that it limits the concurrency by the number of worker thread you have. So by limiting the concurrency, I mean the number of requests you can handle at the same time. So if your system is fine and not very popular, okay, cool, but as soon as you start being popular, this model doesn't fly anymore. And the fact is because it's blocking IO, your threads are going to be blocked at some times. So you are paying a memory cost, a CPU cost, and not making any progress. The reactive execution model is different in the sense that a few IO threads, often called event loop, can handle multiple concurrent requests. But the model is totally different, where we start handling a request and as soon as it needs to do an IO, instead of blocking, it will schedule the IO and release a thread. So the thread can be used to handle a second request. Once this scheduled IO completes, then we can continue the first request on the same thread and make progress until we need to schedule a second IO and other IO and so on. So yes, it's more efficient, but man, it's kind of more complicated too, right? Because you need to divide your program in a chunk of things like this. So it's exactly this. Reactive comes with a different concurrency model where because of this, your application code can be called on the IO thread. Very, very efficient, very, very concurrent, but you need a bottle of warm because that makes the world seem complicated. And it should not be an obligation. You should have the choice of the developer to decide which part of your application is reactive, which part is imperative and mix that depending on your skills and the needs. And that's exactly what Quarkus is doing for you. Quarkus has a smart routine and detect for you whether you're having to say anything, whether your method, your applications is a reactive one and can be called on the IO thread because it's not going to block, it really is a thread and so on. Or if it's a blocking one and in that case, switch to a worker thread pool. So it really unifies reactive and imperative and you can mix them together in the same application where you are going to see that. And you will see it's just, for you as a developer, it just works, no problem. So again, let's go back and talk about frictionless development. And there is no better way to demonstrate frictionless development with Quarkus as doing it. So we are going to create a project from scratch, do some rest API, database access, do some testing, integrate some remote service that exists. So it's the movie database using some full Tori runs features because calling a remote service means I need to protect myself against failures and deploy this to command and test and in my case, open shift. All right, let's have a look at this. So the first thing I will do is to go to this website, so code.quarkus.io I already preconfigured my system here. So we are going to create an application called the movies. We are going to manage movies. And I already selected 10 extensions to do rest, data, link, validation and a few more things that we will see along the journey. So I generate my zip. I download it, it's there, I unzip it. All right, it should be unzipped in my download directory. So let me check. Yes, the movie. Okay, I'm going to just copy two files, one which, oops. Okay, let me check. Ooh, let me check why it didn't unzip it. Okay, so movie two. Three, oops, two, yes, now it's working. So I'm just copying some HTML front end and some config, we are going to see that. I'm going to open my IDE immediately and yes, I trust this project, I just generated it. Here we go, that's my project. And while it's indexing, thank you IntelliJ for indexing everything. I'm going to start my application in dev mode. In dev mode, Qoqus is going to follow my, well, my challenge I do in my code, in my resources and so on. And as soon as I need it, we'll compile and restart my application. So I have always something up to date. So I can try it immediately. So it's starting right now. Yep. So what you can see here is that you see some docker stuff here. Actually, because of the set of extension I've picked, you realize that I may need a database and I don't have one running. So what it is doing is say, okay, you need a database, let me start one for you and configure your application for you. So right now I already have a database plugged to my application. I will have used Kafka, it will have started Kafka automatically. So let's go back to my browser and see if my application is running. Yes, that's the landing page and I have an hello message. So hello, rest is your active, which is the rest framework I'm using. So let's go back here and see where from those that come from this file here and if I say Dev Nation because that's where we are today, I go back to my browser and I refresh and boom, already Dev Nation. So you see it, I don't have to restart on anything in just doing it for me. So another cool thing is testing because when you do application like this, you need to test them. So in my Dev mode, I just press hard and it's going to start the test and continuously do them. So right now it's looking at the test and running them from the Dev mode using a second instance, a test instance of my application and boom, it fails. Why? Because it was expecting rest is your active. So we're going to do something that every developer is doing instead of fixing the bug, let's fix the tests. So like this, I go back here, I don't have to touch anything and boom, it sees the test changed and recompile it automatically. And now I'm good to go. My test is passing, let's start my REST API. So my REST API is going to handle movie. So movie is what I'm going to persist in my database. So I'm, it's an entity and we do that with style. So it's a Panache entity and Panache makes things a lot easier. So a movie has a title and see it's a public field. It has a cover. And it has a rating, which is my personal rating. Let's say that the title is unique and not blank. Well, we never see a movie with a blank title, right? And the rating go from one very bad to five movies I love. We're done for this. So we already have this. And now I'm going to do the REST endpoint in front of that. Movie, movie, versus, this versus. Okay, so that will be listening on slash movies. But using the system I was using before, the continuous testing will be great is to have some tests already done. So I can do that. So I can do some kind of TDD kind of things. That's what I'm going to do right now. I will create a test. Yes, okay. And so I'm going to copy some code. Oops, not just do this. Yeah, so a few tests about my API which introduce two movies, RUMBO and the pioneers and check that we can edit them, add them, delete them and so on and doing some validation tests. So if I go back to my dev mode here, you see that it's already executing this test and they are failing. Why? We forgot to implement the REST API. So let's do this and start with get method. So the get method will get all my movies. Okay, and here Panache is very, very useful because you can just do return movie.list. And done. So let's see, oh, it's still failing. Okay, so maybe I should have a look at what's going on actually in does that work or is that a test program? So I can go to Q slash dev to the dev console. So dev console is your toolbox with Quarkus. It's always running when you are in dev mode and you can go here, go to Swagger UI and see you what you have developed. Go to get movie, try it out and see if it's working. Oh, yeah, but it's empty. Oh, will be great to have some existing movie in my database. So let's do this. I will go back here. I will create a new import.sql file which in dev mode will provide some different movie matrix towers and so on. So now if I go back here and I do execute, I should get my movies. So the get works. So maybe the tests are failing because I didn't do the insertion one. So let's do this. We need to have a way to add a new movie post movie add one. And I want some validation here. So I want to receive a valid movie and valid is what is going to check the constraint that I've added on my movie classes. So the not blank, unique and rating and things like that. And again, Panache makes that very, very easy because I just have to do movies of persist. If it's not valid, it will return immediately and I would just return to movie. That's it. So now let's go back here and it's going to run the test. Oh, it's not passing. Oh, yeah, forgot there was a bug here. You need a transaction. Then let's check. And of course you can toggle the output of the test by clicking by eating whole and you will have all the output of the test. If you need that, I can hide it and we run the test directly from my browser and you see three tests are passing. So we are good here. So let's have a look to our very nice UI. I've done. So it's not nice, but we need a UI. So this is my HTML page I've copied before. So the movies we have introduced. Oh, look at that. This is off four, five, five, two. I want something sorted. Go back here, there. And I want my list to be sorted by descending rating. Go back here with fresh and that's sorted. Again, you see in the flow, you can edit your HTML or the data directly. That's just fine and let's check something. I want to add a new movie. And let's, I loved inception. So let's add it. Okay, so I did at the right place. Okay, cool. But now there is no cover. Hi, yeah. And I don't have the cover for that. So what we are going to do now is to use a remote service, the movie database, to get the cover. So let's see how we are going to introduce this new service. So I'm going to create an interface which is the movie database. I'm going to use the rest client. So the rest client is a way to describe your HTTP interaction using annotations. The same set of annotation as you use for the server side, you use it for the client side. So it starts with register rest client thing. This is a rest client. And then you can add all the operations you want to use from this remote service. Today we need only one, the search one, which is a get on slash share slash movie where you pass a key. Weird thing of this service, you pass a key as a query parameter, whatever. And the query, which in our case does a title. Once you have this, you need to do a bit of configuration which are these two lines you have here. The first one defines the URL. And the second one that I need to copy, it does the root of our covers because the response contains a relative pass according to this one, relative to this pass. So now that I have this, which is very simple because look, it's really the same set of annotation, a bit of mapping, that's it. I can come have back here and say, okay, I want my rest client first, which is the movie database, that's my service, okay, that's my remote service. I want some config property, this one, which is my root for my cover, and I need the API key. And as you may have seen, the API key is not in my application properties because that's a secret and I don't want to reveal that to you. So our mechanism is, can combine multiple config source and right now it's an environment variable and we will see in Kubernetes, it's a Kubernetes secrets. But for you, that doesn't change anything. So now that I have this, let's do a method name enrich, which take a movie and we'll search for that movie on this server, on this service, so movie.title, okay. This returns us a list of results and I need to find, because it's a fuzzy search, so I need to do some filtering. So let's say I want all the movies that were the title match my movie, okay. Okay, and find any. Yes, this is going to be my response and if response, if present, I found the movie, then I'm going to update my movie with the right cover. So root plus poster, so that's all we named it. And I'm going also to update the title to get the right capitalization because that's always made me crazy when the capitalization is wrong. And that's it. I just have to call this method here and done. So now when I'm adding a movie, it's going to go on the movie database, search for it, find it, extract the cover, fix the capitalization and save it to my database. Let's try that. Oops, wrong one here. So let's refresh. So inception will disappear because every time it will drop and recreate my database with my initial set. Inception was of the right capitalization, writing five and no, it's there, right capitalization with a cover. That's it. So let's add another one. Rumble. Rumble, yeah, kind of sweet, right? Didn't age well and boom, I got rumble, writing sweet and so on. So we are using a remote service. So every time when you use a remote service, you need to protect yourself. Here, I'm just going to use faltering on sanitation. I want a time out because I don't want to wait more than one second. Yes, unit for a second. I hate waiting. And well, let's say that if it doesn't work, then I want to retry. And max retry, let's say twice. And between every retry, let's wait for two seconds. Something of that. You can also use a circuit breaker or a fallback or even a bulkhead if you want to avoid video seeing your service. So you have plenty of options. It's very easy. You just configure it. And then you can say, hey, these values are coded. Everything I've write in those annotations can be overridden from the application properties or from any of the configs we support. System property, unvariable, Kubernetes secrets or config maps and so on. So my system is now working. So let's go back here. All tests are passing great. I don't have to rerun them because it continuously runs them. So I'm very happy with this. I got my complete system. So, well, time to deploy it on OpenShift. I go back here. I will go to do slash dev. Here, I'd select OpenShift, click deployed and click deployed. So what's happening behind the scene is that it's going to connect to this OpenShift that is running here. It's again, so OpenShift Sunbox. So you can use it with OpenShift Sunbox. I already started my Postgre database. I already have my secrets for the API key. So TMDB. And it's going, because it's OpenShift, it's going to build it. So send the file there and build it there. And while it's doing so, I'm going to show you a few more things. So the first thing is how does this Kubernetes deploy work? So the thing is you will need to say how you configure your prod system. And in prod profile, this is the prod profile, we want to use the Kubernetes config. So the Kubernetes config source to read two secrets, Postgre and TMDB. Postgre is going to give me the database users, database password and so on. And that's it. I just configure this and it will get the right username password that is stored on OpenShift. Same thing for TMDB. It will add the right API keys that we add. So the movie database dot API keys because that's how the secrets has been structured. Okay, let's go back to my Dev console. What happened? Okay, so we will see if it's working or not. Sometimes it's just nothing, but I can quickly look at this. If the movie, yes, the movies. Did we have a build? The build desk is completed. And yeah, but it didn't work. So let me retry it pretty quickly, deployed. Anyway, and while it's doing so, I want to show you a few things. So remember the two principle of Quarkus, first build time. And we push this idea for every extension we have, but actually arc our dependency injection framework, make it very, very nicely, well, can explain it. So arc at build time found all the beans you have in your class bus. And it found 91 beans because obviously there is a beans of my application, but everything that we provide on this 91 beans, it found out that 65 of them are not used. So it just dropped them simply. So all these beans that I have here are not used in my application. So they're not even declared in my application or run in my application. It dropped them at build time. The second thing is a reactive core. So I'm using rest easy reactive, but see all my code is purely imperative. So it's not because there is reactive in the name, it's just because it use reactive core of Quarkus. And you can get the endpoints core and all my endpoints I have right now don't have a great score because they use a worker thread. So I can update this yellow here, which is here and say, well, okay, you have detected that this method can't be called on the IOS thread, but actually it's wrong. So you can do it. So I just had to add non-blocking or return a completion state or a uni if you want to do that. And then go back here, do a refresh here. And now we have the 101 on 101 score for my rectiveness of this because, well, it use a right writer, it dispatch on the IOS thread and yeah, it's using an application scope scene. So that was very well for the others. I can't do that because they use a database. And if you do that, you will have a error message because you can't block the IOS thread. So let's go back to my open shift. Oh, yes, the noise does work. So it's probably some network glitch. So this is my application. It's connected to my post-grade database. It's running and when I say running, it's also have health checks automatically because I have the health extension. It has the health check for the database and every other extension. So let's have a look. Is it working? This is my landing page. I should have removed it. So I should move this.html. Yeah, this is my page and let's have a look. Inception, still great movie. Okay. Inception, rating, let's have from Bo and boom, that just working. My system is now working on open shift. So let's go back to the slide and conclude this. So that was the demo. Okay, great. So let's go back to see what we have seen. We have seen a project creation from scratch. Rest API, database access with Spanish. Continuous testing. Remote service integration. Folder-on sanitation and deploy to Kubernetes slash open shift. And this in 20 minutes. If you want the code, it's there. So you can just fork it and use it. You will need to have a credential for the movie database, but it's free. So again, Dev services. I didn't start a database on my system. I have no database on my system. It started for me in Dev mode and test mode. And yeah, I don't have to do anything. It just configure everything. When you use things that can be shared like Kafka or broker or something like that, it will share between application running in Dev mode on your systems. It makes onboarding very, very simple. Panache, you access your data with style. It supports active records, what they use, but also the repository pattern. More from, if you come from the spring world, that's probably what you are familiar with. It supports both imperative and reactive. Again, it's unified both. Continuous testing. Well, testing should not be an extra step. You should not go back to your ID, right click, run test and so on. Here, it just run it continuously and report it. Hey, you are debugging something? Okay, but you broke something. So maybe when you are done fixing your bug, maybe you should have a look at this. So before doing a git commit, git push, check your test. It's there. It's running for you, so you don't have to do anything. It's not intuitive. You see you can decide if you want to run them or not, if you want the odd port or not. You can also run them from the Dev console and it automatically detects the test to run. So when you modify a test, when you modify a resource, it will find which method is called or which test need to be run. Dev console, all your tool box, all your tools in a single place. No need to install Kafka cut, a specific swagger UI or Kafka UI or some GRPC curl scene or a GraphQL viewer. No, we provide everything for you. So want to check your rest and point, you go there, you click on swagger, you have a GRPC service, go there, you can invoke it to see if it's doing the right thing. Want to know what's happening in Kafka? You can go and see that. So the Kafka UI is going to be delivered in the next version. Not in the version I use today. Same thing for data sources and so on. Finally, Yamel netes, well, actually Kubernetes but wasn't Yamel, it's integrated automatically. You can configure everything, secrets and the deployment base image and so on. But automatically it gets us, metrics, service bindings and so on. And you just have to click on a button. If you are using Kubernetes and not open shift, it will build the containers for you, push it to the configured image registry and deploy or restart your deployment for you. There is also a remote dev mode where instead of having the application running locally, you can connect to a running pod and it will restart the application in dev mode and all the change you do would be reflected inside your pod automatically. Obviously you need some authentication mechanism to avoid everybody to do everything and don't use this in production but that's very, very useful when you want to debug something that only happening in open shift or in Kubernetes. That's just a scratch. Quarkus ecosystem is huge and we have seen a little bit of crowd, a little bit of cloud but Quarkus can do a lot more than this. You can build monoliths, even with an application, reactive systems, microservices, functions, command lines, administration tools such as cube operators and so on. It's all based on two simple ideas. Build time first, reactive core to handle the IO the right way. Then on top of that, we have an awesome frictionless developer experience where you're never blocked. You always make progress and you go from an ID to your Kubernetes in 20 minutes. If you want to go further, I recommend these two books. The first one from Eric and you can download from free from Reddit developer. If you are a spring developer, it's great because yeah, it will talk with the same lingo that you used to have in spring. The second one, so a little bit more advanced, is going to be published in November. It's reactive system in Java and that I've finished to write with my friend Ken. It's all to build distributed systems the right way with Quarkus using what we've seen today, but also Kafka, MQP and a lot more things, observability and so on. If you don't know what to ask for Christmas, that would be a perfect gift. And sorry for the timeless plug. So that's it, thank you. And I don't know if we have any time for question, but anyway, you can go to Quarkus.io or code.Quarkus.io and start developing and feeling the, well, it's a great developer experience we have and having all the benefit of Quarkus, the permanent city, reactive and imperative side by side. So you can really do what, yeah, the next modern application you build. You want to discuss with the team, you go to Zilip and you can discuss with the team or follow us on Twitter. And that's all I have. Yeah, thank you, Clément.