 Hello and welcome to the presentation about Quarkus, its APIs, and the way they client and break, and how to handle that. My name is Lukas Karici, I'm a senior software engineer at Red Hat, and this presentation is pre-recorded, so I should be somewhere in the chat round, and you should be able to ask the questions. We have a lot of ground to cover, so let's just jump right in. So, imagine, you're like me, you're working on a large software project with lots of dependencies. That, you know, are very complex graph that is interdependent and making upgrades there, usually breaks something, at least. And, you know, fixing that is a lot of frustration to go through. Frankly, most of the time stuff works, and it's wonderful. So, I'm talking here about library APIs, obviously, not about the REST APIs, but just the application programming interfaces in the polished sense of the word. So, this presentation should be about Quarkus. And, from a very high level, Quarkus is just a tool or runtime that you can build your application with, and it provides you using its extensions with a set of libraries that you can use in your application. And the extensions of Quarkus do the magic of build time, you know, initialization, augmentation of your code bootstrapping, such that the resulting code is faster and provides, or consumes less memory than it would if you just used libraries with common Java runtime, like some EE server or spring. So, where are the APIs here? Obviously, the Quarkus core needs to provide some API to the extensions so that they can instruct it how to do the build time initialization and code augmentation bootstrapping. And there are also APIs between your application and the libraries that the extensions provide to your library. So, yeah, the extensions, as I said, provide the APIs to you and consume the API of Quarkus core, and there is a lot of them. I counted 187, but I'm sure there's more. And the thing is that every upgrade of the third party library that the extension provides to your application can, in theory, break the API because of the third library breaking the API. So, you as extension author need to be very careful about what and when you upgrade, and you need to make sure that you don't break your use of Quarkus users with that. Quarkus core, as I said, provides the build time augmentation and bootstrapping and is used by extensions to do this magic. So, there are many moving parts in the API of Quarkus mainly because of the extensions and the third party libraries that they bring into the picture. So, you know, releasing a new version of Quarkus is usually quite a complex juggling act between providing new features and fixes and not breaking the API. So, it would be nice if there was a set of automated checks that would prevent, you know, accidental changes and human error in this complicated process. So, there happens to be a tool called RevAPI or RevAPI, however, we want to pronounce it that I've been developing for the past seven years. And it provides the API checks to the users. It's got a Maven plugin, third party provided cradle plugin, and it's mainly geared towards library authors. So that, you know, during your daily work when you're developing new features and fixes, you remind it during the build that your changes are breaking the API so that you can make them an informed decision. About whether to do that or not. For that, it's got, as I said, integration with build tools and it's got reporting capabilities so that you can then, you know, provide some summary of the changes that your new version of your library is making. And it's not just about Java code, it's going beyond that currently into YAML and JSON. And with that, let's see a demo of how RevAPI works within Quarkus and what it provides to it. So let's put ourselves in the shoes of an extension developer and have taken Flyway extension of Quarkus as an example. And let's see how our, you know, daily work would look like with API checks in place. In Quarkus, there is a profile that you need to activate for the API checks to kick in and that's what we are going to use here. So I know that the Flyway extension has upgraded the Flyway library since 1.10 release of Quarkus. So let's now, let's imagine I just upgraded to 7.3 as a developer of the Flyway extension. And I want to make sure that everything is still OK API-wise. So I'm going to run Maven with Verify. I'm going to activate the API check profile. I'm not interested in tests in this case. And here I'm saying that I want to check dependencies. That's something that the Quarkus configuration for RevAPI switches off by default, because when Quarkus uses many of its modules interdependently, it produces basically false positives. But in case of extension, I actually do want to check my dependencies, my Flyway library that I'm exposing. So let's switch that on to true. And because RevAPI integration in Quarkus is still working in progress, I need to manually specify the base version I want to compare against, in this case 1.10.0 final. Otherwise, the default behavior of RevAPI is to use the latest released version, the latest non-snapshot. So let's run this and see what we get. Hi, Lukas from Future here. I'm speeding up time so that we make it to the presentation time limit. Thank you. And we see that stuff failed. We see that there are some methods removed in Flyway API configuration. Another one of those. Another one of those. I'm not sure, for example, if this is... I don't know Flyway, so maybe this is okay. But again, this is not the point that I want to make. I want to make the point that there's a tool that makes you aware of these changes. There is a method signature change, but it's somewhere in internal packages, so this is possibly okay. And another one in internal. Okay, so what are we going to do? We upgrade it to 7.3 Flyway library and we really do want that. So we take a look at this list of API packages reported by RevAPI and decide what to do with them. For example, here I would say changes in classes that are considered internal by Flyway, I guess we should just ignore those. So to do that, we need to tell RevAPI to just not even bother with these. And in the RevAPI parlance, this is called filtering. So we are going to filter out anything in an internal package of Flyway. So let's go to our IDE and now we're going to tell RevAPI to just ignore everything in internal packages. I think this should happen for any version of Flyway extension. So we are just going to put this in right in the POM file of the Flyway extension so that it is applied always. So I've prepared what we need to put here. So let me just paste that in and I'm going to explain what this all means. So we are configuring the RevAPI-Mable in plugin and we are modifying the analysis configuration. So we want to filter out certain types from the analysis. So analysis configuration is basically configuration for all the RevAPI extensions that are going to be running. So one of them is RevAPI filter and we are going to filter elements meaning, you know, classes, methods or fields. And we are going to exclude and this is a new thing that has been just added to RevAPI after like two or three years of me working on that. And this is very, I think quite advanced filtering for Java. This is specifically for Java and we are saying that we want to exclude any type i.e. class interface annotation enum that of which the full qualified name matches this globe pattern. So org, Flyway, whatever and there needs to be an internal package and any type after that. So with this in place, let's see what we get if we rerun the analysis. Oh, of course, it's not Flyway, it's FlywayDB, sorry. Okay, so these internal, the changes from the internal packages of Flyway are gone, but we need still to, you know, justify these changes. And the way I want to do this is that I want our users, the users of Flyway extension to be aware of these changes, you know, because we're upgrading, we're providing the Flyway library to the user application. And so the user when upgrading the Parkways extension should be aware that that brings along some consequences in Flyway as well. So the way to do that is not to filter out these elements, but to basically make them reported or documented, but not breaking the build. So the way we want to do that is in Parkways, there is a setup to provide like external files that can provide changes that have been deemed necessary per version of the extension or the module in question. And that file should be located in the root of the module that is exposing those API changes and the file should be called APIChangesXML. The way it's set up in a Parkways configuration, this file should have versions as its root element and then each child element should have the version that those changes are relevant for. Now, the development version is always 999 snapshot in Parkways. So this is the way we, it's currently set up that we need to reference that version. It's not ideal and we will probably work on that, but that's the way it is right now. And we want to say that we need to change the classification or change the way certain differences found by Revapi are reported. So there is an extension of Revapi called Revapi differences. So we will need to configure that here to basically take these changes into account but not break our build. And so the way we are going to do that is to consider all of them as documented, which the configuration is set up such that documented changes are not breaking the build. And it would be good to give a justification for these changes. So let me just place that in from my notes. So we are just going to say, you know, we think these API breaking changes in Flyway are okay and we want to move forward with them. Even though they're potentially breaking your code because we don't think that's going to either happen or that it's really necessary. So and then we are going to list the differences. If you look here at the build results, Revapi during when it found the problems, it output some suggestions what to do with them. You know, for example here, it suggests that we should ignore certain the change of removal of this method from Flyway API. Now we don't want to ignore it because that would make it disappear from reports and from the build also. We want to document it so we are not going to exactly use this. But we can we can just copy paste this here and copy the item as well. And we can ignore this. So this is saying that now we're going to document this change instead of us breaking on it. You know, the method, the removed method, this concrete method is going to get documented and we're fine with the change and we give justification for it. We gave it here so we don't need to repeat it here. And the same thing for the rest of the changes. So let me just paste that in from my notes. And if we save this file and rerun our analysis or build, we should get no errors and our build should be green. Yes. So the build succeeded. So everything that we configured to ignore or document has been accepted. And you know what? There's been quite a few changes in the API and this extension is supposed to be stable. And I'm personally not too comfortable with the amount of API changes that are happening in Flyway, even though they may be, you know, well intentioned and everything. But, you know, I want to give certain API stability guarantees and those changes don't allow me to do that. So let's just demote this from a stable extension to a preview and run the build. And what I want to show you here is that Revapi is not limited to just Java API checks. It's slowly moving, you know, in other directions as well. And one of those is the ability to check, you know, JSON and YAML files and stuff like that. And when we are talking about the integration of Revapi checks into Quarkus, we realize that, you know, there's a good potential for writing custom extensions just for Quarkus. And we've just started experimenting with that. And one of the results is that we have a dedicated Quarkus extension for Revapi. And what it does currently is kind of simple. It just looks at this Quarkus extension YAML file and reports the changes there. And so here you can see that, you know, it breaks the build because you've changed the status of the extension and that has consequences. And therefore it should be documented. So again, we want to document this change. Now we've done that before. So let's just continue doing the same thing. In API changes, we want to document that we are changing, we are documenting that we've changed the status. So again, with this in, the build should succeed. Yay, it succeeded. So that's all too good. You know, for me as a developer during my day-to-day work, I can upgrade what I need and I'm kind of pushed or forced to document the changes that I'm making as a Revapi configuration now. But you know, that would be kind of bad if stuff ended there. We want to have a way of reporting all those changes and reporting our justification for letting some of the API changes through. So again, the configuration of Revapi in Quarkus has been set up to produce reports. And those are put into target of the module that is being built. And one of those reports is a JSON report that just will list everything about the found differences that Revapi knows about. So if we look at this file, we can see all the differences that we've seen before and maybe even more of them that were not deemed breaking the build before. Like for example, here there has been some method added in Flyway API, but adding a method to a class is not a breaking change. So this didn't break our build, but it's documented. And because it's not breaking change, it doesn't have any justification because we didn't provide any. But the changes that were breaking the build and that we needed to put into our Revapi configuration have the justification here in the report that we entered in the configuration. And this is saying that removing the method from a class is a breaking change, both as a source incompatible change, as a binary incompatible change. But still we thought that this should go in our release. So this is no longer a breaking change, but a documented change because we said so. As you know, authors of the extensions, we have full power to do that. And these are the details that Revapi provides about the change. And so with this JSON file, basically the intention that we have in Quarkus is to use this JSON file and basically work with it further, produce different kinds of reports, which is easy to do. If you have a JSON file that you can then programmatically massage in a whatever way necessary. Another report that is being produced is basically just for human review. It's an ASCII doc file that gets built. And this is the same thing only as an ASCII doc document. So if you want to take a quick look at the rendered output. So this has a lot of work to be done on this. But yeah, so you see that the reports are not just limited to JSON or whatever, but they can also be nice graphical human readable things. Yeah, so basically that's that's all I wanted to show you. We have API checks. We can leave out certain stuff from analysis altogether. We can document certain API changes such that they are still known or documented, but they don't break the build. We are not limited to just Java checks, but we can also check other types of files, like for example, certain descriptors in YAML or JSON. There's a plan to check the configuration options that Quarkus exposes for any changes. You know, that's going to be based on the annotations that you put on the configuration classes in your extensions code. There could be other things that could be something like a Pico CLI extension for Revapi that would look at the annotations that Pico CLI is using for, you know, command line arguments. And then you would have API checks on your command line arguments. There are many things that we can do and then we can then more importantly report on. So, yeah, that's it. And so, and we've seen all that in running in Quarkus, but this is still a work in progress. We have many great plans with it to make it really nice and, you know, smooth experience. So, yeah, looking forward to the future, maybe you will want to help us out. And so, as a final note, let's write a window of change in the APIs smoothly, because that's what you want. You don't want surprises. Here are the links. Quarkus is obviously on its homepage and is a great project. If you want to take a look at Revapi, I would be thrilled. My name is Lukas Grici and thank you.