Spring I/O

Spring Time: From REST to GraphQL by Frederieke Scheper / Peter Eijgermans @ Spring I/O 2026

49:34 · 13 Apr 2026 – 15 Apr 2026 · YouTube

About this talk

This talk covers the practical journey of using Spring GraphQL in conjunction with Angular to create a DJ application. The speakers, Frederik Scheper and Peter Eijkemans, explain the advantages of GraphQL over traditional REST APIs, particularly in handling complex data queries efficiently. They walk through how to set up a Spring backend that uses a GraphQL schema, resolvers, and live updates through subscriptions, allowing for real-time interactions with the front-end. The talk also touches on using micro front-end architecture with Angular, making it easier for teams to work on different components independently while utilizing the same GraphQL contract. Additionally, the speakers demonstrate handling audience interactions and music requests through their application.

Full transcript

[music] >> Hello and welcome everyone. Thank you so much for coming here at the end of the presentation, at the end of your day. Hopefully, you're still awake to see our practical journey with a Spring GraphQL. So, let's get started because we've got like ground to cover. So, my name is Frederik Scheper. I'm a Java architect and a Code Smith and I'm working for Sogeti in the

Netherlands. And I'm currently being contracted by the Dutch National Police. And this presentation partly originates with my journey over there where they actually um are using GraphQL and well, I had an opinion and uh well, we'll walk through it and I'll show you stuck I hit my toes and whatever happened. But then again, I'm here with Peter. Yeah, I'm Peter Eijkemans. I'm also a Code Smith and

a front-end architect. Uh works also for uh Sogeti in the area. And uh I work for the Dutch Railways where we also work with GraphQL. But let's start with the with the game. Why GraphQL? Uh let's start with it. If we have to our uh here this uh application I've created here it is a beautiful uh DJ application where we can uh okay, here's some music. So,

are you still awake? Yes. Because today's about the party. So, this uh this presentation, [music] it's all to keep you awake and get you awake and it's about the party. It's about party, yeah. So, uh you see a lot of data here. You have a lot of We have also you fetched some uh lot of uh songs and tracks here where you can select. You can also

uh react on the on the atmosphere in the uh in the crowd uh when the energy drops or uh when the dance floor have to fill up. You can also uh do some uh requests on the audience and uh some recovery. okay, let's further go further with the slides. Yep. So, we have here a uh context diagram. It shows uh the system in uh at a high

level, of course, uh so very very simple diagram. The front-end is uh Angular and Apollo uh we used uh in the client and in the Spring GraphQL as our back-end, of Surprise. Surprise. This is this is the single API entry point for our application and uh the back-end is driven by um the GraphQL schema. And that is our contract. And this is really our our Yeah, you

can say our API between the front-end and the back-end. And also it is driven by the back-end is driven by resolvers. Uh those are mappings operations to code. And also we have services and repositories in the back-end. And how does the data flows, uh? The data flows from the front-end sends queries and mutations uh via HTTP to the GraphQL via GraphQL to the back-end. And the back-end

receives subscriptions as live updates over GraphQL web sockets. And the back-end server resolves requests using schema and resolvers. We see uh And uh in short, the UI asks exactly what it needs. That's what the GraphQL the strength of GraphQL. And uh uh the back-end enforces one type of one type of API contract. And the live updates keep uh the screens in sync. So, let's go further. The

why. Okay, uh today's journey we're uh talking about uh the what and why and the how and uh the why we start where where uh the REST uh yeah, where does the REST stopped uh scaling for us, uh? And where helps GraphQL us with so solving. And also uh the what's about the main model, how it is set up and how does it works and how does

it wires together with Spring. And also uh the how and how do we uh how do Angular uh uh yeah, build we have built micro front-ends with Angular and how do we consume uh those data in the front-end with micro front-ends. Anybody work with micro front-ends? All right. Yes, you? One. Okay, good. And on the other end, the GraphQL is uh we work with GraphQL already? Okay,

really good. Then we'll have something we'll have actually have a lot of ground to cover. So, maybe we should speed up a bit because otherwise we're going to be right out of time. decision criteria at the end. And so REST still works, uh? That is in some cases uh where and also it doesn't. So, uh where does it work, uh? For if we have uh one consumer

or one simple uh application, it is uh always good to uh to use REST. And uh there's also a lot of good tooling you have you know them all already, uh? Open API, Swagger and HTTP caching is also uh out of the box with REST and the GraphQL that gives uh yeah, quite difficult to uh to solve that. Uh but okay, it is doable, but uh and

every team uh yeah, knows how to works with REST. Just to be sure, everyone work with the Spring Web MVC? One, two, few hands. Four, five, goodness, thank heaven. Uh where uh yeah, okay, uh where it broke down. Uh yeah, for us the DJ screen needs a lot of data, sessions, tracks, songs and uh artists and uh we can solve it with one uh fat end point

REST end point, but that is not uh what we want to and uh also uh use uh yeah, live data and then uh we we use REST, we have to pull the data every time. We don't want to do that, so we use subscriptions. the data is pushed. Okay, let's go. >> [laughter] >> Let's go. Let's go. Uh here you see an end point, a get end

point. So, this is basically the REST tax, the the thing that hampers us in our application if we would do it like this. Like this, you see that this end point delivers us loads of data. This is too much. And uh yeah, we have a little small small front-end, you don't want all those data. And you at the end you see this timeline and of course the

timeline grows and grows and grows and grows and grows and every time this the response will be larger. So, bad idea. Bad idea, yeah. Yeah. You can also do some hm? some events. And if all goes well, it also ends well. And then you see it growing, I think. Yeah. You see it there. Yeah, yeah. Like more. Okay, more and more. Bad idea, just don't do it.

Yeah. What if the client could ask what it needs, uh? So, uh not via URL, but via query. You can ask what we what we want in the front-end. the client declares exactly what it needs and the server answers precisely what we want. And uh the same uh yeah, we we can use the same end point in the same same schema, the same API. And uh okay,

we can also query what we And how do we do that? See we see an example of a query, uh? The current mix session. And we map here to a current mix session field and it's uh contains an ID and also the all those tracks and all these data that we need uh DJ app. And uh we have also another query. We uh you also uh make

on this same field, the current mix session field and it uh only returns uh one track, the last track. And uh the song with the title and artist, but it doesn't contain does not contain the audio file. So, it's quite flexible Yeah. to work with GraphQL, yes? Here you've got this audio file. And there it is. And basically as a client, when you ask the server, you

can ask oh okay, this time I need I do not need the audio file, so just skip it, right? Yeah. So, you skip skip what you want or add what you want. And here in Angular in the front-end, you see how you use it, uh? We uh use also Apollo as dependency. And we can uh yeah, quite easily you can uh grab the data via the Apollo.query

in this case, we want to have the audio session um uh data. Uh yeah, okay. This is TypeScript, you know, everyone familiar with TypeScript? Yeah, okay, good. One more? Okay, good. I go I already said the schema is a contract, that is the API, that is uh contract between the front-end and the And the schema is defined in SDL as uh that is uh SDL is schema

definition language. We uh we can define it before we implemented this uh something, of course, uh it's our contract. And uh the query is uh yeah, public API surface. You see a type query, we define it. And uh also the field current mix session what we showed already. We can uh okay. And also it contains a mix session and uh and also enum we can define here.

this is uh in a nutshell the beginning of our talk, uh? The party. Okay, Let's just get right? Because what's the party about? Everyone been to a party? Oh, it's so late. Hey, goodness. Yesterday, are you still awake? Good. Okay, because a party, you know, there's this venue and a lot of people there and what they do what do they come from? To dance, right? And what

does a DJ do? He plays his songs to get everyone to the dance floor. So, just don't come up everyone to the front cuz it's going to get like really crowded here. And what the crowd does, the crowd can react like, "Yay!" Or silence. Or they can send audio requests so hey, I want to play this song, please, right? And then DJ, what does a DJ do?

Well, he prepares his session, right? So, he has his own track library that he can play and and from that track library he selects like the tracks that he thinks in advance that'll be useful for this specific party, right? So, during the party, he selects tracks that and he can add tracks by reacting to the crowd and to keep the energy up. I want music, DJ. Yes.

So, this is the Let's get a lot of music because we want to keep you awake. Not sure if it works. It works. Shoot. Yeah. Okay, [music] good. Let's get going. we have this Spring application and the URL for the GitHub repo I'll post up at the end so you can all look at it. It's also the Angular and presentations there, too. So, no need to take

any photos or whatever. So, technically a Java architect and I love domain-driven design. Anyone love domain-driven design or hexagonal architecture? Good. Good. Good. Excellent. Love it. So, we have the music library and the music library is basically the static library that the DJ has. And the session track is derived from it at run time. And that is basically the the the session that is evolving during the

the party, right? So, what does that look like? Well, it's got a domain model. So, we have it's a bit small, isn't it? Can anyone read it? It's really really small. So, okay. I'll just walk you through it. So, we have like the crowd events. We have the disc jockey. We have songs. Well, you have soundtracks. There are also cue points. A cue point is basically something

that actually that is part of the music library. So, a song has a certain The DJ, I've heard this from a colleague of mine who's actually a DJ. So, he knows. I'm not. That's why I'm a bit warm. Okay. So, a song he partitions it sort of and says, "Oh, okay. If I start at that specific point, then that really helps get like the audience up." And

at the same time so that's the way he reacts and prepares his session. And there's also songs and artists, of course. So, we have the session model and the mix session now is the aggregate root. Basically, the aggregate root is the in terms of domain model is that where you ask the question. So, give me whatever something I need I need to do something on my mix

session. I've I've got like a an audience request, right? Or play. And now let's get to the schema definition language and we've seen like the domain model well, although it was small, hopefully you get the idea. So, we have like the mix session. We have session tracks. We have songs that all of them have properties, right? So, a song has properties has like a title and an

audio file and an artist who's playing it. the client declares what he wants. So, continuously we have like this this double argument, right? So, the server on the server side, we know what we have. We have like everything and the client say, "Oh, okay. This time around, I only need this, please." So, that's basically the the general One of the differences with REST. So, how does this

actually work in Spring? Because we're here for Spring, right? Spring GraphQL, the schema, The mechanics. First, just a few wiring points. So, a Spring MVC the the the standard REST controller, he has like you have like this this class, the controller class that has all sorts of get mappings and and whatever mappings, not only get mappings, of course. But, you have the mapping per URL and on

the other hand, we have like the Spring GraphQL and there's only one controller and the query mapping there's like quite a load of them and I'll show you what they look like and what's good about them and what what's good about them, right? So, we have the routing. So, the routing on MVC is based on the URL and the method which can be like post, put, get,

patch, whatever. And on the other hand, we have like the schema field name and that maps straight to the method name by convention. You can override, but well, I've never done that. I've never seen the use for it. So, there's field resolution. So, the on the REST hand side, the controller always returns like this huge big JSON file or could also be the Anyone still using XML?

Good heaven. Thank you. Okay. [laughter] So, on the other hand, we have like the schema mapping and that's where the client that's basically the server side mapping of the way that the client can select whatever it needs. The client shape on the server fixed and on the other hand, we have like this So, basically the tracks and last.int. I'll show you that in a minute how that

works. So, basically you can restrict what you want not only by saying, "Oh, I I don't actually need the author." I can also say instead of all the tracks of the current session, just give me the like the last five or the last one only, right? So, you can as a client you can restrict in any way you want. And I think that's actually really cool if

you do it right. And that's one of the things that I uh that I found weird at the at the Dutch National Police where they actually don't do it. So, hey, okay, you have this fantastic tool. The idea was right because they have like this We have like this front end. They have them, too. They have like five different tiles and the users can select different tiles

and depending on that, they could have updated and changed the query to say, "Okay, for this micro front end, I only need this." But, they keep asking like the whole lot every time. And then basically the idea is Well, then you lose your advantage. So, I've got like a battle to pick there. You get the idea. Yeah, I know. So, we have the like the request chain.

I'll just Well, this is actually how it's implemented and maybe the most interesting bit is so we have like the we post like always to /graphql. The query then the the execution GraphQL service is a Spring Framework thingy. The query mapping is that that is what we code ourselves. Then the controller applies the domain event. sends back an updated aggregate if there's a mutation, otherwise there's no

aggregate updated, of course. And resolved value is sent back as a part of a JSON response within the field. So, let's have a look how this actually works and let's see some code because it's like really nice. I want So, basically we have like this is the implementation of the disc jockey GraphQL controller and we have it in IntelliJ as well. So, let's switch to that. And

so, DJ controller. And what you see here is this is let's just go to all the top. Okay, so here we have like Is this actually readable for anyone in the back? So, I thought so. Let's just make this a bit back bigger. >> Okay, nice. Yep. Okay, good. Better? Okay, good. So, we have like As you can see, this is like Spring, right? Anyone know Spring

here? I expected like all the hands up. Come on. Come on. Yeah. Wake up. So, we have like the query mapping. So, this is like the current mix session and we can go straight to the GraphQL schema and this is our actual schema. So, it's actually not so large. We have like a couple of types, right? So, here's the mix session and the mix session and here's

the track and this is the parameter, the argument that you can give, right? So, let's get back. So, here are the mutations. These are the queries. And this is the entire schema. >> okay. The current mix session maps with the other one. Okay, so let's go to the GraphQL controller. So, we have like the current mix session and basically all what it does is like this. So,

the session service give me the current session and what that one does is so, let's go to the implementation, of course. So, find current or else throw. Give me an exception if the idea is unknown. So, if we don't have the idea of the current there's no So, this is find current. Goodness. Right. So, find current. What? Find all stream, reduce, whatever, something. Give me the Okay.

And on the other hand, we have like the get session by idea. Hey, gosh. It's a repository. find by idea or else throw. Mix session not found, right? So, and the same with track. We can Where is the Let's just go to the presentation back. That doesn't work like that. So, this works. So, we have like the current mix session. So, these are the codes. Let's and

see what happens. So, loading. With like a good mix session ID. Right. And paste it and oh, this is something oh, goodness. I know what happened. I guess I pasted the wrong ID. Good. Excellent. Is this actually readable in the back? Right. So, here's like the data thingy and there's the mix session and the mix session gives like tracks. These are the tracks that have been currently

been played and I can also do like something different. Hold on for a sec. At this presentation presentation, I still have to get used to reveal JS. Sorry about that. So, I can ask um get the mix session by Oh, that was that one actually. Haha. Good. Um the other one I wanted to paste like the current mix session. So, this should work. okay, good. Paste. Yes.

Good. So, here this is like returns all the tracks in the current session. So, that's the way you can like query and how it works for uh queries. So, next we also have mutations because hey, what's life without a what's a database without something that ever changes? So, crowd cheers. Right. Mix session service apply crowd cheer. We'll have a look at that because that's like a bit

more difficult because there's a publisher in it with a subscription, too. So, we'll come back to that one in a sec. So, the mutation mapping for request from audience. So, basically what this one needs is the ID and the ID of the session and the track name that it has been requested and it calls apply request from audience to the mix session. So, let's have a look

at how that like what that looks like because it's like sort of similar. So, it's in the IntelliJ. Go. Go. Go. Yep. Okay. Uh this is the wrong class. Let's get to the controller thingy. Sorry. Huh uh request from audience. So, we here where we just had like query mappings, now we have like at mutation mapping. Logging uh what else is it then? Just Spring, right? So,

wire it up. We have the mix session service apply the request from audience and return the updated session. Let's just take a quick look what that thing does. Basically, it's a transactional method and it has this ID and it says apply and publish because there's something going actually, this one also does apply and publish, right? Because apply and publish is always We have like this client which

Peter and that wants to be updated on what happened in the in the front end, right? So, let's get to that in a minute. How fast can you do this? >> [snorts] >> Um so, next thing that is like really interesting is the way resolving of the fields actually work. So, you have to code it. this is the way the tracks. So, that is the where the

um >> [clears throat] >> As I showed you, you can like give me the tracks the last five or the last one track, right? And this is how it works. So, this parameter this this last is just an argument and it can be null. So, if you don't specify it, then it's just like mix session dot tracks and if it's we asked too many, then just return

the entire list and otherwise, I want to return the sublist with only the last one or five or last whatever, right? So, how does this actually wire in Spring Um it's all in same schema GraphQL. So, we had like the query, we have the mutation, here are the subscription. So, that's when the session is updated and when the crowd vote tally is updated and Peter will tell

you more about that. But, the thing that I wanted to look like was like the uh this one. So, the mix session, right? So, tracks last and here you see here like the the uh the mechanic thing and here we go to the schema mapping which is incidentally also in the GraphQL controller because we put everything in one class because why not? Then at least your class

becomes like well, a lot of lines, but not so many. So, here we have So, this is basically how you wire it up on the server side. Right? At least for queries and mutations. And now let's make it difficult. Oh, errors. Oh, interesting. So, we already incidentally saw accidentally saw the error that happened when I asked it to give me um the session of an ID that

does not exist and it was not in the console ID, it was like in here. So, uh this is what returns when you get the session when you ask the session of an ID that does exist and when you get one that don't doesn't exist, then you get here like the errors. Does anyone know what actually what you usually do on REST? Like HTTP error raw codes.

Exactly, return codes. In GraphQL, you always return 200 usually and you put the errors just in the as as a JSON object and so >> returns 200, you say? >> Yeah, as a rule. Yeah, HTTP is 200 always. And there's no data. At this time, you could have. But, so and how is that wired? Well, not that one actually. Uh let me go to the right correct

class. hm hm hm. It's like next to it. Here's the exception resolver which extends a Spring Framework class and resolve everything that happens into one single error. It says oh, okay, if you have like a DJ console exceptions, put the error code in it. If you have like a mix session exception, well, you can like gracefully handle the exceptions in the way you like. Right? You could

also return say oh, okay, actually I can imagine you calling a backend service, right? Which we at the Dutch police do like loads and loads and loads of times and just one of them doesn't answer or not in time. Then we can just aggregate whatever we have and spawn that back and just ignore whatever failure or give that to them. So, unfortunately, we couldn't get this for

you, but we could get the rest. So, hopefully this at at least helps you in the crime. Thank you very much. Um this is actually something that I really like about GraphQL. Who does testing? Unit testing? TDD? Good. Because this is So, at [snorts] the Dutch National Police, we were also using like GraphQL Java and that's basically the stack on which Spring GraphQL is built, right? So,

Spring GraphQL is an extraction layer on top of com GraphQL Java and the Dutch National Police, they have they have built like their own wiring layer because well, you can. >> but, I really like the the way this is like So, basically your test should get current mix session given mix session service that current session will return a given session. Then document name execute gives me this.

And of course, we can run Oh, and also are people loving ArchUnit, anyone? Okay, good. Good. Good. Yeah. I'd like to see more hands for ArchUnit. ArchUnit is really, really good. If in [clears throat] this in this application, it it keeps the GraphQL layer clean in the sense that as you can see here, my service can no classes that reside in the service package can depend on

controller GraphQL or whatever classes, right? So, basically this is the way that you can enforce with your tests that your that you don't have like the wiring. Which is like horror and I've seen it. Let me see how much time I have left. Like 20 minutes. Okay. Uh test. So, this is like the test. Right. Let me just run one test and see that it works. Run.

This is the should get current mix And it passes. Good. Uh let's get to the subscriptions because that was the missing link and I'll just skip this diagram because it's So, basically what happens is the service says oh, okay, something has happened. I need to push data. So, it publishes the data in this case the session. It's emitted. Well, it uses flux and it filters the session

ID so that a given client got only gets like the updates of his or her session. And then that's basically what happens. Okay, with web sockets. Uh does anybody works with with web sockets or Good. More web sockets? More hands for web sockets? Service and events? Anyone for service and events? Okay. Good. That's also like really Um let me just Oh, sorry. Yeah, because the real-time server

push and hopefully this works. It usually does, but sometimes well, it doesn't. So, we have like this Let's just do this one first. So, we have like where we just had like query mapping, mutation mapping, we had like the schema resolver and now we have the subscription mapping. And what it does is give it an ID, in this case the ID of the session that has been

updated, the mix session that has been updated. It returns, hey, presto, a flux of the And we connect Well, of course this flux has like only one because there's only one session that has been updated, right? But you get the idea you could like return more and um So, it concatenates the the current session to the flux and it streams it back. Good. Are there questions until

now? No? Because I hope like quite clear, but Yeah. So, um this get session by ID why is this Oh, this is the service mutation. Yeah, okay. Exactly, that was what I wanted to show with the apply crowd event. do the demo first. Um let me see. Hopefully, this works. No. No, yeah, this one. Uh demo with GraphQL. Yep, okay. Hopefully. Just give me the URL cuz

>> then I can't put it in here. I hate this. Yeah, okay. These are the demo days. Okay, that's one. And here is the other one. Paste more GraphQL. Thank you. And then This is like the mix session updated. I wanted to put this one over there and then So, basically here we have like the stream. It should I would expect it to not Hmm, we'll see

if this is going to work. I highly doubt it. Let's just kill the server just for a sec because hey, who notices? Is this actually Yeah, and this is the test and that was actually not the one that I wanted to do. It did not. Let's get the application running again. No, this one play. Yeah, okay. So, now it's running, right? This Now it's like this you

can stop it, but it shouldn't be stopped. Now, if we right? So, the crowd cheered event into into this one. That's an event. Okay. This is the event and if all goes well that ends well, then the other one should be updated. Right, as you see it does, right? So, basically we get this server sent push from Yeah. So. Okay, right. Um and uh let's get back

to the code. So, that was this demo and do we have time? We've got like time to Go for it. Yeah, okay, good. Let's go for it. So, let's get to the apply crowd cheered event. Uh right. So, we had like the mutation mapping. That was the one that looking for. It's in the controller and look for the apply crowd cheered. Okay, so we had like the

crowd cheered event. This was the mutation that we just sent over, right? Mutation crowd cheered event, right? With the ID of the session. We had like this and the mutation applied apply crowd cheered And what does Yeah, okay. The implementation. Hello. So, what does this do? As you can see, this is like a transactional uh it gets a session by ID. It applies the event and then

it saves the repository and publishes the updated uh saved uh mix session, right? And what does this emit next? What else? What would you expect? And it will publish to all the clients. >> Yeah. Okay, yeah. Good. And I think that covers like the server A quick recap. >> [sighs] >> So, what do we have? We had like the schema definition. You put it in source main

resources, whatever in the GraphQL thingy and Spring GraphQL picks it up. We had like the query mapping and the mutation mapping which are sort of are the same as the get mapping and the post mapping and the put mapping and whatever on the Spring WebMVC side, right? So, the internals had like the schema mapping that was the way things actually work and are resolved. We had like

the our extended class of the data fetcher whatever something except adapter and that's the one that actually does like the exception handling. We had like the GraphQL test which is like amazing combined with ArchUnit and we have like slices that have been like recently tested. No no cross wiring of controllers and GraphQL and whatever things. So, and then the push layer we had like the subscription map.

We have the flux, flux concat over web socket and the servers calls the publish and never imports a GraphQL class because we hate Just don't do it. And now it's Peter's time for the for my best friend. That's that's a lot of information. So, we we know a little bit of front end now. It's uh more lightweight now. In the beginning we are talking about Angular and

uh and Angular and also a little bit BFF solution. Have you heard of BFF? Back end for front end solution? Yeah, okay. >> Good. Very good. Uh for the front end we use the micro front end architecture. You see here how it is made up. First in the micro front end architecture always there is a host application. And the host application is responsible for routing and also

authentication, authorization and also for which micro front end underneath are loaded on the screen rendered on the screen. And in this application we have two remote applications, two micro front ends. They are called remotes. and the the advantage of micro front end architecture is that team A or team B or team C which is working on the host they can build their application independently. So, this is

what you want of course is the same as with microservices. You want to build your on the front end the same of course. And this what what is good is about this is that you can um yeah, you can load this application and also stitch it together at run time. So, and all they all use the same schema schema and all the use the same uh GraphQL

contract. In our application we use we've set it up in this way. Uh for the host application we this our DJ application and underneath we have also I haven't shown it to you already not yet. I have also a vote application where you can vote some uh some music with a QR code and also a another front end with some information on it. So, only for the

demo. And yeah, this is the setup a little bit in the spring graph is is running on 8080. So, yeah. And now we are using a module federation. So, have you heard of module federation for the front end for micro front ends? It's very good stuff because you can uh easily load this micro front ends uh together, but you can also load in this I we use

Angular load Angular will load load it one time. So, for every all when you have 100 micro front ends in your application, it will not load it 100 times, but one time it will load Angular or your other shared shared libraries. So, uh Take a look at module federation. In this part we use native federation which is much better, but okay. You can start with module federation.

And yeah. Um what do I want to say about it more? We have a we have not so much much minutes anymore. Okay, the BFF strategy is which we have here. Uh for example, web application which needs all those fields which we want and then we we can have a module mobile which want to want to show only the status or some fields and or a dashboard

with some other parts. And then in the middle we have the BFF which routes all those uh uh yeah, the maps the fields to the right service underneath uh seen it already in the talk of of So, this this is our BFF solution. Okay, the demo payoffs. Let's go further. We have not so much minutes anymore. Here you see it from the front end view. You see

the same flow a little bit what we explained already, the above part. We explained here the query. We do a query uh for the critical user journey I show you for the DJ console of course and we do in at the boots at bootstrapping of the application we query the current session and then we show the current session with all the songs of course and then we

also do a subscription. We set it up for for events and also in the in the end we have also we can also do some mutations from the from the front end of course and the mutations also also results in events and it will be published to Okay, let's go and uh do some music. Let's imagine the >> Something went wrong. >> Yes. And uh We were

we were dancing and some somebody Oh, it's not working at all. We're dancing and somebody wants to uh do a request >> [music] >> This is actually according to my colleague something that something that really happened. Like he makes a mistake [music] and suddenly everyone just walks away from the dance floor. It's like oh horror. Yeah, there's no people on so I we recover of course. It

is not uh not a big deal of course but okay. >> Yeah, for him it is. Yeah, it is. Okay. So basically the idea is when that happens he said I have to play like a track at the peak level to make sure that everyone comes back to the dance floor and thinks oh okay. Oh, this was just like 1 second Yeah, that's that's that's the let's

say that I We recover it. Okay, we firstly we do a here a setup how it works a little bit in code it so you request from the audience. We apply a request and then we do a apply event. And on the other hand we have also the apply recovery from the from the DJ and he has also the uh the his own event to recover it.

So it is all the same structure so it's not so so not so difficult. Uh okay. This is uh okay what we what we use of course for the we've talked about it already the current mix session. And also the apply recovery of also is own mutation query. Uh let's go to the crowd vote first. We've created also a what if I was talking about micro front

end so we have a micro front end with uh some rest end point where I show you I have also another micro front end which uh where we can vote some data some some music. So I suggest you can Can you check? This actually should work. But then so from the internet you go to my laptop and then it goes to route through the angular application right?

And then to and then to the back end and we >> see we can show it yeah. Actually so the crowd vote should look at that. Okay, everybody is voting the same. Okay, that's that's Yeah. Can anyone vote for Chrome Thunder? Yeah, good. Okay, this is this is really a little bit about how it works with subscriptions and the real time data so You as you can

see this really really really works. And it should play in 2 1 second. Is it this is the music on? No, not yet. Yeah, you have to play the winning Oh. Yeah, play it. Push. That's the one. >> Okay, bye. Okay, [music] thank you >> Yeah, help. [laughter] So this is the part of the code we use now for the uh for the audience scans the the

QR code and we use there the this mutation query for the cast crowd vote mutation. And it receive the slot. I can also show it in the screen of course but what is it? Okay, later on. There was like the three QR codes and each one was a slot. Basically that's the idea. >> I show you later. And also we have a for the you saw it

already the crowd vote live the dashboard. With the bars? >> Yeah, with the bars so this is the other one and also the DJ applies the winner so this is the third one. That was the button. Yeah, yeah. Yeah, let's see if they can what's Okay. Let's see the URL. Right. We already have QR codes we have it ends with slash slot zero. So how does that

how does it map to the code? Can you you I want I can show you hopefully if we've got time. So what where are we start at in this so this is angular magic and I'm not an angular expert but but it's it goes into app.routes.ts so we have like the vote There it is so this is the path I'll try and you correct right? So we

have like the crowd vote page component so So yeah, that will grab here the From the query parameters we grab the slot the slot number and then the application notes knows from okay that that slot we have to uh This is pipe take yeah map >> Here it will. Yeah. Yeah, okay here it will go and actually where's the query this Apollo mutate oh yeah and here

are this when we go to um the queries these are the queries so these are the queries that the front end actually knows so you can see quite a lot of them. So well and the general idea is that every client so now we've got like only the Apollo client with a with the dashboard but if you have like a mobile phone usually you would have like

less on the screen right? At least in the old days you did. Let's finish it. So you You can go for it. Yeah. So that is the way that crowd votes work and the bars are updated via the web socket and it's like I think Well, Spring GraphQL I think I really like it. So we want music so let's wrap this up we are out of time.

So question one, should I migrate? Well, you never know of course but a couple of questions that you can ask that can help you guide towards REST or towards GraphQL. So if you need HTTP caching let me just start in the middle just go for REST right? Because uh GraphQL and caching that's not a good idea because you have like this post and it's a single end

point just don't do it. Right? So if you when if your team is only experienced with REST native and you don't have time to invest into GraphQL just don't do it. Stick with GraphQL. On the other hand if you have like a lot of different consumers and that that they have which have different needs and also depending on the use case so we at the Dutch National

Police we actually have like loads of mobile apps for different policemen on the street and also the the investigation crew and they all have like different needs. So that would be like a really good use case if like and etc. etc. So should I migrate lean towards REST or lean towards GraphQL? Uh the API shape we've seen that one versioning is something very important. Who loves versioning

with REST? I don't. I hate it. Because it's always breaking things. And on the other hand you have like GraphQL and it has additive by default and you can deprecate fields and say okay this one will be gone in like sometime and then you give your clients to gracefully time to degrade and of gracefully time to upgrade whatever. So the error model in HTTP you have in

GraphQL you have like the HTTP 200 as we showed. Uh the tooling maturity for REST is like excellent with open API and swagger. And we have like the schema introspection I haven't showed you but both in GraphQL and in Spring you can enable introspection and then you can just see what the schema is that is exposed. Uh over and under fetching that's basically the problem that you

usually have with the REST way like get what like this big responses and and it gets a res a response whatever you don't need and on the other hand you have GraphQL where it's not necessary. Um it works first it survives production. Anyone goes with the application to production? No one? Oh good. Haha. Thank heaven. So there's a lot of things this demo application it's not hardened

whatever there's no Spring Security in it but you can put it in there and it's just like it's Spring you've seen it right? So this just works. The difficult bit is once again things pagination can also enforce that with GraphQL. I haven't showed with scrolls and windows and all these nice things. Um security. Does anyone like security? Good. More hands we you should have really everyone should

stick up their hands with security. Security is like important and you can also so for the Dutch I also have this for other government clients. So depending on so the same person depending on the role he's currently using can have different authorization. So when I am I am uh uh forensic officer I may see more or different things than as a regular person at the office. Right?

So the same person can have different authorization. You can all do that in GraphQL. Right? So pre-authorize it's Spring right? Um and subscriptions well it's like difficult just skip it. So in the end what else is new? Use the right tool. REST isn't wrong. GraphQL isn't magic. The question is who are my consumers? And can they live with what I give them today? And if the answer

is no that's the problem and maybe GraphQL can help you solve it. Here are the links and we can put them back on. Any questions? We've got like a couple of seconds. Maybe after the session you're all there. Uh so thank you so much. Okay, thank you. [applause]

From event

Spring I/O

13 Apr 2026 – 15 Apr 2026

All event videos
Back to Watch