 So, I'm Ron Siegel. I work at Red Hat. I have for a long time. Most of the time I've been working on a project called RESTeasy, which is partly what this is about. Now, since this is the GRPC conference, I won't assume that you know much about Jakarta Enterprise Edition Java, though it's not going to be due. Yeah, so what's Jakarta EE? Formerly known as Enterprise Edition Java, a collection of specifications, APIs, reference implementations, and technical conformance kits for building large applications. And it's an umbrella which covers a lot of different specifications. For example, beam validation allows you to put annotations to constrain the values of variables. Context and dependency injection is an inversion of control mechanism. JSON serve what's particularly interesting to me is Jakarta RESTful Web Services, which is what I work on. So the history of Enterprise Java is this. In the prehistory, there were servlets, which was folded into the first edition of Enterprise Java in 1999. I can skip most of these, but the one that's interesting is that in 2009, Jax R.S. was introduced, which is now called Jakarta RESTful Web Services. And what is Jakarta RESTful Web Services, according to the web page, provides a specification document, a TCK and foundational API to develop web services following the representational state transfer or REST architectural pattern. Well, it's a little bit controversial whether a Jakarta RESTful Web Services really captures the original intention of RESTful. But it's Jakarta RESTful Web Services, so sort of by definition now, it is RESTful. Some of the characteristics are that there are client server systems with HTTP transport layer. On the server side, dispatching to the appropriate method is based on annotations, representing, for example, URLs, HTTP verbs, media types. And now it supports asynchronous and reactive paradigms. Now, at Red Hat, there are two relevant open source projects. And in fact, each one of these could be a talk. I didn't have time to do much with Wildfly, but Wildfly is our community implementation of a Jakarta EE application server. REST easy is an implementation of the Jakarta REST specification, and that's where I work. And so I've condensed the entire talk about Wildfly to one slide, but it's an interesting slide. What we've made it possible to do is to take a... If you package up a GRPC application into a web archive, into a jar, and you drop it in a deployment directory, if it has some class that extends io.grpc.bindableService, which is the kind of thing that comes out of the GRPC compiler, then Wildfly will notice that, it will register this application with the GRPC subsystem, and then it can process GRPC invocations. And in addition, the GRPC system that you've deployed can take advantage of all Wildfly's facilities, and Wildfly implements all of Jakarta Enterprise Edition. Okay, I just realized that this slide's a little ambiguous, and it says, why do we care? I wrote this for Jakarta people, Jakarta EE people, and so why would we care about GRPC? If you ask Google about the prevalence of searches, and in two particular searches, GRPC and RESTful, well, they kind of track each other, but you'll see that RESTful has more searches up until it crosses over in April 20, 2022. If anyone knows what happened then, I'd be interested. But then, since then, more or less, GRPC supersedes RESTful. So that's why it's interesting to us in the Jakarta EE world. Okay, let me take an example. Question? The question is now out to the community. It doesn't matter. We used to do RESTful, but that's not REST. RESTful is the term used by Jakarta. What's the general term referring to REST? Yeah, well, it starts out as a general term for a way of developing an application. Representational, straight, state, transfer. I guess it's a REST. I just say Jakarta REST. Here's a simple example. There is a definition of a type called greeting with a string field. That's on this side. This method here is a Jakarta REST server method. And it's annotated with a few things that allow the runtime to dispatch an invocation to this particular method, including the HTTP verb and the part of the path part of the URL and so forth. Now, if you wanted to translate that into GRPC, it would look just like you expect. There's a greeting message type, and there's an RPC greet which takes a string and returns a greeting. Okay. Now, what this talk really is about is captured in this slide. I want to make it possible for a GRPC client to invoke on an existing Jakarta RESTful application. And that looks like this. Suppose you start with an existing Jakarta REST application. One of the things, the first thing we do by scanning the files in the directory and looking for the appropriate methods, we generate as automatically as possible .protophile, an IDL file. Given that IDL file, you can write a GRPC client with respect to that protophile. But you can't invoke directly from the GRPC client to the Jakarta REST application. So we need some intermediary classes to make it possible. So now the GRPC client invokes on a GRPC service on the server side, and that service is going to do whatever magic it needs to do to transport that into a Jakarta REST invocation. So it goes into the Jakarta REST runtime. That returns a value that goes back through the intermediary code and comes back to the GRPC client. Now, to make all this match up, there are some problems, some semantic problems. One of the differences that in Jakarta REST, the HTTP information is exposed to the application code. So you get to see the headers and the verb and URLs and so forth. There are other semantic differences like Java has packages and Protobuf doesn't. Java has inheritance and Protobuf doesn't. Java has interfaces and Protobuf doesn't. So these things need to be massaged. Now, the first step, like I said, was to generate a .protophile and the algorithm looks like this. Now, we give it a pointer to a directory tree, which contains classes. A resources class is one that has methods that are annotated appropriately with Jakarta RESTful annotations. So for each resource class, we look at all the resource methods. For each resource method, we look at the entity and return types, as the input type and the output type. And for each of those types, we take the transitive closure, supertypes, fields, inner classes, and so forth. And from that, we generate a .protophile. I just want to make a call out to the Java parser project on GitHub, which is what we use for parsing these Java classes. And then we end up with something like this. There's a service. This is what we would get from that simple example before. A service with a greet method. But rather than getting a string and returning message type, we've defined a general purpose incoming message type and a general purpose outgoing message type. And those look like this. So we have to expose a lot of things that normally wouldn't be exposed, URL headers, cookies, HTTP methods, and the content of the actual message. And similarly for the return side. Now, here's where we have to start finessing things because Protobuf doesn't have inheritance. So what do we do? Let this general greeting extend the original greeting type. And we'll have a new method that returns a general greeting. So the way that looks in Protobuf is, well, we have a new RPC for the general greet message. It also gets a general into the message returns a general return message, but we've now defined a general greeting type. And let me say two things about it. One is another thing we have to finess is packages. And so we use underspores to basically fake the notion of a package. And now general greeting is a subclass greeting. We have a new field greeting underscore super that holds a greeting type, which has all of the inheritance at fields. And general return message. Before it just could return a single greeting. It had one, there's a one of field and the contents of the field are all of the return types that can be used. So we add a new general greeting return type. Here's another place where we have to finesse. Suppose that a method is defined to return an interface rather than a class. We don't know until runtime what class it's actually going to be. So we finesse that by using an any field. So you can pack anything into an any. And we find out at runtime what's going to go in there. Note that on the server side, the packing, the unpacking is handled by, is handled under the covers by those intermediate classes. On the client side, packing and unpacking has to be handled explicitly. Now, here is one of the important intermediary classes. So a GRPC request comes in. And we want it to be processed by a Jakarta RESTful service. So we take the GRPC invocation, turn it into a Jakarta RESTful invocation, create an environment that looks like the environment that the Jakarta RESTful service expects. That code looks like this, and I'll go through it quickly. For instance, create an HTTP servlet response, an HTTP servlet request. We find the actual servlet that's meant to handle this application. This is a technical thing. I'll skip. And now we pass the invocation into the Jakarta REST service. It runs. It passes back an object, and we parse that object into a type understood by the protobuf in protobuf. And we send that on to the GRPC runtime and back to the client. So here's what this is about. We're starting with an existing project, I call the target project. And we build around it a new project, contains the old project that it has the classes that we need to do that translation from the GRPC world into the Jakarta RESTful world. And moreover, there's a maven archetype that pretty much embodies all the steps that need to be done to build the different pieces. Now, if you're interested, the RESTeasy project itself is at this URL, resteasy.dev. RESTeasy GRPC, the stuff I'm talking about now, is a subproject and the code and documentations are at this URL. And so I spoke faster than I expected to. There's two minutes left. Any questions? Oh, yes. And thanks for the talk. Could you go back to the walkthrough in one, two, three, the long time? I don't see where GRPC was made. No, the walkthrough the long time, the intermediary runtime. So this one? Yeah, yeah. I don't see where the GRPC request is created and that the GRPC code was made. So when you run a protobuf descriptor file through the compiler, it produces a file with a stub method for each RPC, right? So that's what, and then you override those stub methods with the actual logic, right? And normally the logic would be business logic. In this case, the logic is what you need to do to translate the GRPC invocation into a Jakarta REST invocation. And notice that the first quality, the first perimeter is a general entity message, right? So that gets sent from the GRPC client. So it builds that, we get it and pass it to this method that overrides the stub method. Yeah, that makes sense. Okay. So the use case here is the RPC client make a quality server which has a Jakarta REST handler. Yes. What about the other way around when you actually have a REST client talking to a server? Right, a Jakarta REST talking to a GRPC server. There's another project somewhere, can't remember what it's called, where they do that, right? So this is just what we're trying to do to expose what we've got to the GRPC world. One, two, three, yes. I have a question around the proto files. Can you go back to the previous slide? Further? The one that says the proto files are generated. I'm wondering, are those automatically generated, the proto files? Yes. So we parse the... What are these resources class? Are you saying the Java.class or...? Okay, we start with a collection of Java classes which are the content of a Jakarta RESTful application. So there are a bunch of methods in there that can respond invocations. Oh, so you read from those Java files and then generate corresponding proto files? Yes. So yeah, we look at the Jakarta RESTful service in all of its pieces and then we see what types are necessary that are going in and coming out and also the fields and those types. So those fields have to be defined and so forth. I see. Thank you. Now, I should say that I said we try to automate as much as possible, right? So there's a certain amount of information you can get by scanning all those classes. But let's say it's possible that there are some types that don't show up in that scan and you might have to intervene and add those so that they show up in the dot proto file as well. Cool. I was curious. Your users, what's the general use case? What are they trying to solve? I understand the general idea, but what's an example? Well, I can say that we've had some requests from users to pay attention to the GRPC world, right? And that might mean that they want to be able to use GRPC for its efficiency. But in the context of a Jakarta RESTful existing service, right? So that was one thing. Another is just the other part of this that I didn't really talk about much, which is having a GRPC service running inside of a general purpose application server so you can use all the facilities of the application server. So what I saw was some sort of vague description of what some customers would like to see. And this is what it turns into. And no one has stopped me yet. Maybe it's what they want. We'll see. Okay. Thank you. Thank you. You mentioned Jakarta Supported Reactive. Is this how streaming is supported? Okay, so REST easy is our implementation of the Jakarta RESTful spec. And we've built out some reactive stuff starting with, well, this is still, this is part of the part of the definition of Jakarta REST in the spec, the ability to return like a future, right? So we've added that, but we've also added the ability to return streams. So that means that at least in our implementation of Jakarta REST, we can return streams. And what that means is if my goal is to be able to translate any Jakarta RESTful application into Protobuf, I have to have a way to handle that our server to client streaming. But fortunately, that's one thing that actually Protobuf does better than Jakarta REST, because it has streaming in both directions. So there is a streaming ready to be used, right? So we take a method that does streaming and turn it, let me see. Basically, it means this overriding method is going to look a little different, right? It's going to pass a sequence of objects into the responsive server. And that's how we would handle what I'll call Jakarta RESTful streaming. What is a Java API, a Java type for the streams in the pure Jakarta world? This is actually something that we added in REST easy, right? So you have a method that returns some reactive type, like it can return a... Oh, it's been a while since I worked on it. An observable or there's a newer version of observable. So we can have a Jakarta RESTful method that returns a flowable. That's good it is, right? And that's not part of the spec yet. Okay. But the long time only supports the server streaming, the server to client streaming, I guess. Right. I think it's worth suggesting to the Jakarta RESTful committee, which I'm on, but I haven't done anything for a couple of years. But maybe we should also add streaming from the client to server, right? And well, that would be fun, but I don't know. Thank you for your questions. Thanks, everyone.