Devreal

Reactive Systems: Creating Full Reactive Applications with R2DBC

Reactive Systems: Creating Full Reactive Applications with R2DBC

Recording: Reactive Systems: Creating Full Reactive Applications with R2DBC

and i'll just say a few words and we'll get rolling so uh hello everybody uh welcome to this reactive systems meet up uh it's also joined me up with sf scala sr spark and a few other meetups uh and it's a meetup open worldwide as we do now uh on zoom my name is alexis krabroff i am the uh founder and organizer of this meetup since 2015 uh and recently uh i became a general manager of uh the reactive foundation which is a new linux foundation organization specifically uh set up to support uh cloud-native applications with reactive streams and also uh building reactive systems as resilient message driven and elastic right so there are two meanings which uh we care about uh and uh i'm very excited to um to introduce our first talk on r2dbc it's a it's a reactive driver for relational databases uh it was originated at pivotal now which is a part of vmware and it's an open source project which is on the verge of being uh inducted in the reactive foundation and so uh we're very excited uh to have a talk on this from rob hatchpath who is the developer advocate at mariadb i found his excellent blog post it's a true kind of ground up movement the r2dbc is a very vibrant project already it has a website it has a twitter handle uh it has a github it has a lot of stuff and and so i'm really excited that rob uh basically found it and played with it and obviously maria db is a very uh well-known and liked uh company in in in in the community so uh so i think it's a really great uh great talk to have so rob uh without further ado i'll uh let you run the show uh if you guys have questions the way we do it type the questions in the chat and rob can review them as he goes he can choose to answer them right away or he can uh wait until the end and uh obviously in the end we can have a discussion with everybody speaking on zoom uh using you know video and voice uh if rob you feel like you want to take over voice uh at any time just you know ask folks to say whatever they want to write the thrill up to you how you want to run the q a and without further ado welcome rob yeah thanks alexi and yeah thanks very much for reaching out and let me letting me join up on this meetup i'm i'm pretty excited to talk about it as you mentioned i'd written a blog post and i had done a session at mariadb open works which was digital this year on this and at the time r2dbc the implementation from radb r2dbc uh was an alpha too um it recently just uh switched to beta1 um so we are kind of moving it along the pipeline but as you mentioned mariadb popular but not very large from a corporation standpoint so each of our connector developers actually has two connectors that they work on right so the person who works on r2dbc also works on the node.js connector and so we've got this kind of uh massive workload you know among these developers so moving it just along you know as fast as possible but one of the things that really helps is joining meetups like this and you know getting the interest from you and you know others basically to say hey this is something that's really important to us we want to see some traction into it because you know like any company unless there's some kind of interest coming into it this is you know something that you know won't gain traction unless we actually can provide that feedback so this is really helpful um anytime you want me to come in and talk and to be honest i would just like to join the meetup to learn more about it as i mentioned before i'm in something that i'll caveat i am actually pretty new and that's that's bright so hopefully your screen's not extremely large or in a dark room but i am currently working developer relations at marie db um i have been an application developer for you know over a decade at this point starting in web i spent a long time in mobile i worked at a company called xamarin which is a cross platform solution which eventually was acquired by microsoft i spent a lot of time working in c sharp and so i'm actually newer uh to the java side um and you know jbm in general and i gotta say i'm a huge fan of a lot of things that i've seen so far um and i'm really excited to actually be working with rtdbc specifically and we were talking before lexi that i i actually have been in the process of writing a book um on r2dbc and it is a an extreme learning process because writing a blog post right is one thing and you know writing blog posts is is something different than uh than writing a book uh it is it is you know i have had to be very scheduled and uh very organized in order to be able to do it but it's been a really good process and i've learned a lot about mostly what i didn't know and especially things that i didn't know i didn't know um so that's been pretty exciting uh to to go through that and if you want to get a hold of me anytime after this you can you know hit me up on email obviously twitter after seeing me write some live code which is the demonstration portion of this you're welcome to go and judge me uh on my repo out on github as well it may be warranted after you see some of this code right i do say i am newer to java so don't judge me too harshly but do judge me because i i i think it's probably warranted um so here's the agenda really that i'm going to go through now i like i had mentioned and some of these are tagged sorry for the kind of mariadb uh templated um presentation usually whenever i do meetups i like to keep the marketing aspect out of it just because you know i'm really more focused on the development aspect of it but i did give this a similar presentation i modified it for here um to a group at the marine db open works conference and like we had been talking about the beginning of this is that you know the idea of reactive programming and really using you know reactive systems as a whole and this whole concept of reactive development um is kind of foreign to people so i like to start it off um not knowing anything about the audience with an introduction and hopefully it's not too basic for you all uh an introduction to reactive programming and mostly it functions as a reminder for myself and really kind of sets the stage as i work into r2dbc what it is what it really means as far as development in the future of reactive development within relational databases and how we can actually use it and i use all that really as the foundation because i want to jump a decent amount of time into a demo now the demo itself isn't anything complex but what i like to do is start with nothing at all right i'm going to use spring initializer and i'm going to create a new maven project and from there i'm going to create just a simple spring boot application that i'm going to integrate into mariadb's r2dbc connector directly into marie mariadb database um so we can see in a matter of about 10-15 minutes of just writing code that you can actually get started using it with spring data repositories in the r2dbc integrations that they have available now so i will stop blabbing on this agenda and move directly into it so reactive programming what is it well when i first read the message that's out there um is the first you know kind of introduction in the reactive programming i mean it reads that you know a declarative programming paradigm concerned with data streams and the propagation of change now that is a lot of computer science shoved into a single sentence and so um you know having more of a background and more imp imperative approaches you know not really familiar as much with declarative programming as a paradigm and you know understanding at least a vague sense of what data streams are i mean i know what data are i know what a stream is i can make some assumptions but there was a lot of stuff that i was really missing here and so the way i approached it and again i will take any and all feedback so you know as i go through this if there's anything that's off or something that needs to be you know more detailed you know dive into certainly let me know but like with a lot of things i like to think of it in the context of something that i work on right and where we can all probably relate to is this idea of building a client application that communicates with the server in some way um we can think of it maybe with web requests right where you're actually communicating with an api which i'll show a little bit later but this idea of you know requesting information there's some work done on this server specifically a thread on this server and then you get a response back nothing game changing about that but what we may not well we probably realize but we may not necessarily know what's happening here is that any number of things can be happening from some third-party system and in this case relevant to us is a database right where we've got some kind of process happening in the database so when you kick off that initial request the the server thread itself part of the work that it needs to do is actually communicate with the database but at this time while the database is off doing its thing the server thread itself is blocked from doing anything else right because it's essentially waiting um for the database to do whatever the heck it's doing um and so the common response has really been to lot of times and this is still really a common response is to simply spin up more threads right um be able to create more server threads so that you know while it's still cranking away on that database request we may have a second request come into the server um that we handle on a completely separate thread and of course you could imagine that if we expand this out horizontally you could have all kinds of threading going on here and that's a lot of context to manage right um it becomes a lot more complex in code it certainly becomes a lot more resource heavy um it just isn't the most efficient way and as we were talking about alexi you know before it's that once you realize that this isn't exactly ideal for we'll say some situations i mean it's there's certainly no silver bullet in computer science i think we all know that um but when you start to think reactively in the sense that you may receive the request right on the server thread and the server thread can then kick off the request to say a database or some third-party system without expecting a response right this idea that it can shoot off something and then not necessarily have an idea of when to receive something back other than it's going to receive that back at some point then that opens up the server thread then to continue work on the same thread in respect to something like request to or another request after that and so this really starts to dive into this idea of more of a declarative type of setup where you're not concerned with managing the workflow steps or exactly knowing step by step what needs to happen other than you just need a response or a result of some sort in this instance from the database and so as we start to think of this declarative approach the next thing that we really think about is okay well how do data streams come into this right well at first whenever you first think of a data stream right i mean it makes sense you're like okay well there's point a and there's point b and there's simply a stream of data between the two right but if you start to peel back the layers of that you start to understand okay well what's available in an actual data stream right what what's the breakdown here of of what i'm sending what i'm actually using and you know any updates and you can think of a data stream really as or really the anatomy of a data stream as of course it needs to be able to start an event of some sort you need to send information which is the variables that you see here and then there's basically two things can happen it can either complete as you'd expect or it can have some kind of problem and all of this of course is happening over some duration of time but that's really kind of a problem right is that you don't really know what that duration of time may be you don't especially know how much information at least from the raw standpoint of what's going to get sent over and so there needs to be or there was there's other ways i guess to do this as well but reactive streams back in 2013 was a specification that was built to kind of wrangle this together and create a standard approach for being able to manage this um and again it is a specification so as we'll look we'll see different implementations of this you know some of which we'll actually use within the application um and others will be using the specifications to help create other specifications in the case of r2dbc but with any specification in java or any i guess respectable specification it does come with a technology compatibility kit which is a series of basically check marks or tests that it has to pass in order to be a fully fledged implementation but the most important part that we want to get into and you actually mentioned it before briefly was that this idea of non-blocking back pressure right so when we consider a stream and we're not talking about the back pressure that you may this is my small attempt at a joke right the back pressure that i get when i read or try to understand originally what reactive programming is what i mean is if you consider something like a fire hose right or you're drinking water out of a hose if like the instance of a data stream you can think of the stream itself being the water right and that you're receiving all of this water or the emitted water and elements underneath is that you may end up not being able to handle the full brunt of this and so back pressure in this instance allows you as the person receiving the water the ability to say squeeze that hose to say no i can't really take that much or you know i need to you need to stop it completely and we can resume a little bit later and from a very simplistic standpoint makes sense right is that i want to request from my point b to point a hey i'm ready for more items or more elements go ahead and send those to me right seems very straightforward and in this case we can actually start to pivot into what we think of as a publisher and a subscriber right where somebody's or something is publishing information or data in this data stream um that we can actually use an observable or and then this subscriber which actually takes this information [Music] but the problem here is that if just left up to this very simplistic design you are really just offloading the problem from the subscriber to the publisher right because the publisher may end up not being able to send as much over to the subscriber as requested and so you run into this issue where you're really just creating a backlog really on the other side and so though you can certainly solve that there could be any number of ways to do that that's where reactive streams come in as an api or a specification really to be able to create reactive solutions with non-blocking back pressure so we won't necessarily dive so much into the intricacies of what's involved with the api other than the fact that you can think of it as a collection of interfaces right that can be implemented and used in an actual implementation um which is something that we'll see as we start to dive into r2dbc now again why is any of this is important right and we you probably thinking i thought this guy worked at a database company he hasn't talked about a database at all up until this point well we really need to get an understanding of reactive programming and how it exists right now you know within the development world to get an understanding of why r2dbc exists and first and foremost of course i think we can all at least acknowledge that it really is the next frontier of you know specifically in java and the jvm at this point for high offensive efficiency applications but it also exists in you know in other mediums as well and fundamentally it's because we are creating a non-blocking approach of being able to efficiently or most efficiently be able to use our resources and and optimize you know those that resource use but a lot of times it's paired with this idea of asynchronous that's probably because within the definition we talk about asynchronous data streams but people tend to think of this as asynchronous as in threading right and though it certainly can be used in an asynchronous fashion it's it's not it's not necessarily coupled to a sink right it's agnostic to the fact that it's synchronous or asynchronous the idea that we really want to take here is this control of back pressure or this use of back pressure um to be able to create the most efficient non-blocking environment for applications and this is really important for databases specifically relational databases because if we think about nosql implementations they've actually had reactive integrations and reactive implementations for a while and it's taken a little bit for relational databases to catch up and part of the reason for that is that there has been a an api or a standard that has existed for a long time in jdbc right the java database connectivity api but unfortunately as reactive as our applications are our jdbc api is actually blocking by i mean really by design right i don't know if it was necessarily meant to be blocking uh but the approach that it's taken within the api is blocking right within our database operations and so we actually don't have a truly reactive application unless we've got that non-blocking behavior at the database level because at some point something is being blocked in this case we're just pushing that down to the database enter r2dbc well r2dbc if you hadn't caught on to the name now is two rs for reactive relational database connectivity and as alexi mentioned it was something that has been spearheaded by pivotal and has really started to take off and we'll see a little bit why that is uh in the next couple of slides but first it's it's good to define a goal before we start jumping into the actual uh specification and then an input input and actual implementation of that specification and so we need to understand okay so we have jdbc right and it exists why can't we just use or why can't we just modify the existing jdbc api well there are several goals that we'll get into but obviously like jdbc it needs to fit in the jvm platform but it also needs to fit into the reactive model seamlessly and really innately it needs to fix a couple of things that jdbc has opinions about right so for anybody who's worked with the jdbc api it can be a little too opinionated about certain things which starts to put a little bit more pressure on vendors that may end up having to implement or create implementations off of the api um and so it ends up being a little bit of a pain in the ass if you ask anybody that's really working with jdbc and ultimately they need to keep the focus on sql and relational databases and try to keep this new specification as simple as possible [Music] and this is all in a hoax right that rather than having to kind of modify or you know i guess change jdb jdbc api we can use a new specification r2dbc to actually then provide the ability for an implementation or a vendor to come in and create a driver that's fully reactive and non-blocking at the database level [Music] so why a service interface well instead of actually having just a ton of implemented code which may come with a ton of opinions right because um certain things could be decided right if we're talking about reactive development there are several reactive frameworks um and you know different libraries out there that certainly r2dbc could have used um to you know everything from an actual publisher implementation to be able to put inside the specification but instead the creators of rtbc dbc wanted to keep it simple so that the driver authors and the api users actually could make the decisions and implementation right so they'd have a lot of flexibility and this boils down to a couple of reasons i only added a few of them in here but some things that are really annoying are like the special character like question mark binding within jdbc and url parsing the fact that urls are pretty standard um and have to be re-implemented or re-parsed with every driver and have an implementation ad these are some of the things that become a little bit annoying and so with r2dbc what's nice is that though it seems like a small addition is that it will handle things like url parsing for you right where you understand things like the scheme a particular driver in this case would be mariadb you then add information to actually connect to the database and then information for querying or setting up particular configuration differences between the databases themselves but all in an effort to unify how you all url parsing is done but that's really only the beginning of it right the whole specification itself comes with a variety of different interfaces which we'll see now i'm not going to dive into all of them but i am going to take a look at a couple of them and anytime you've worked with the database some of these things or probably most of these things are going to be pretty familiar to you and that's this idea of a connection factory which will create and kind of maintain these connections from there you of course want to work with a statement to be able to create a query um off of that connection which will then return results and each of those results will have a collection or a tabular tabular value of rows which we'll dive into so we're just going to take a look at these five really quickly but one of the things that i want to point out is we look at a connection factory first and foremost is well one the implementation or not the implementation the actual interface here is extremely simple right but one of the things that we'll notice off the bat with r2dbc is that of course as i've you know been mentioning it uses reactive streams so that whole span or you know kind of tangent that i went off where it wasn't i guess a tangent but it's with the idea of setting up okay here's the importance of using the reactive spring streams specification and we're using that as the foundation for r2dbc and so as you would think of a connection when you go to create a connection typically you go you create it and you get back that connection object right whenever you ask for it but of course now we're actually going to be subscribing to a publisher to be able to return at some point our connection object which we'll dive into a little bit later here as we kind of continue down this chain we can see that connection comes with a lot of the same functionality that you'd expect and is available in jdbc but of course still uses reactive streams and uses reactive development in order to be able to provide publishers rather than actual values that are coming back and we'll see how we can actually use those within an implementation so everything from you know being able to control your transactions to be able to create a statement and a statement you can create off of the connection that happens immediately but one of the most important methods probably in the entire specification is execute right where we're actually returning a publisher of some object that it basically inherits from result or extends result sorry extends result in this case the interface and so from there then it really just boils down to options that you're used to having within database connectors right this ability to bind um your parameters so being able to set special characters within your sql query like a question mark or a colon and a named value and then being able to dynamically set values into that all of this comes baked into the specification for a statement within r2dbc and from there you're able to return a result now a result is simply two things it's going to have um a it well it's going to either return one of two things it's either going to return a tabular set of results um where you're going to get row information row metadata information or in the case of an insert or an update you're actually going to return account right where it tells you how much or how many records were affected by whatever query modifying query that you've been doing whether you've executed and a row then simply allows you then to look at column information or cell information based on a column name right so if you have a column identifier whether it's an integer or whether it's the name of the column itself then you can pull it out all of this very straightforward something that we're very familiar with but again this is just a specification there's nothing here that's an actual implementation and we won't see that until we jump into an actual driver or vendor implementation of that and in this case of course i worked for mariedb and the logo has been splattered all over the place so you could guess that i'm probably going to use more edb as the example but we'll see that this process then of being able to use the r2db specification comes from creating a mariadb specific implementation or implementing these interfaces to create an implementation to use as a driver and so of course in order to create a connection you need a configuration and that's going to take all of the you know the values that you expect from a database from the address of the database the port number username password and you're going to be able to build a configuration from there you can use that configuration to instantiate a implemented mariadb connection factory so we saw the connection factory interface and the mariadb connection factory simply implements that interface to be able to allow us to create a connection factory from there we can use a connection factory to create a connection now as we saw before it is a publisher that gets returned so you can use block basically to say hey no i i really need a connection because i can't do anything without the connection being established so i need that before i do anything else [Music] from there then you are really kind of opening up um the floodgates now i promise all of this verbosity is not the way that we're going to be doing it um this is simply to show how you would use the implementation from a kind of more manual or raw perspective so bear with me for a couple more slides and then we'll jump into an actual implementation um that will not be using this this very uh verbose approach uh but we really start by using the then established connection object to be able to create a statement and we can expect that you know we can enter in our query as a string just you know as expected from there we can execute execute it by creating a flux object which is something with project reactor which i'll jump into here in a little bit and once we get the results we can actually take and accumulate using map and flat map again i'll dive a little bit more into this later but we can basically accumulate these these elements that are emitted into a singular publisher which is our flux of type task at that point which is going to allow us to essentially as we see here use the row data and the metadata from that row then to be able to map that into our task object and return that through a publisher or publish it then now we can also as i mentioned before some of the things that were available from the specification are things like bind and we can see that very simply we can actually use bind as named or you know simply just parameterization where we can actually say hey um you know at this particular instance or maybe you wanted to name it i want to assign this value to my query and be able to execute that from there we can expect to receive maybe a single value which is what mono it is 0 to 1 essentially elements that you can expect back as opposed to flux which is 0 to mini or 0 to n elements that could be emitted and we can expect from this case that we want something like a you know a number an integer that basically tells us how many records were affected but as i said before all of this was extremely verbose right we got a pretty good idea in the first part of r2db section of what the actual specification is and then the second part i kind of went off the rails showing how you could implement it but that's great to be able to see it and if you wanted to create a data access layer all on your own and be able to manage all of the data access objects and you know work with um you know all of the the built-in functionality to do that and then be able to abstract away um as much as you wanted to that would be great but a lot of times we don't have the time um to really worry about that and luckily there's a lot of libraries out there that help us integrate not only with reactive development or reactive programming libraries but we can also use it to be able to integrate into rt r2dbc and so we're just gonna i'm just going to go ahead and jump directly into a demonstration i am going to be using spring initializer and i just want to be able to create a maven project right because in this project i'm wanting to take my watch out here i'm going to create a maven project as i mentioned i'm going to be using java though of course you can generate a couple of other languages you see here i'm just going to use the latest stable i'm going to keep everything basically default as far as packaging and the version number that i want to use i'm just going to change a couple of the names here i'm going to change it to the group to mariadb.com.mariedb i just want to change the name of the application to to do and i'm going to flip over to the dependency side because there's a couple of things that i want to add first thing i want to add is i want to be able to create a reactive [Music] a reactive environment for my spring boot application using um what is known as webflux and nete which we'll dive into a little bit but i'll keep the focus mostly on r2dbc from there i actually want to take a look at r2dbc well if i type in r2dbc i can see a variety of different options and what you may notice here is that mariadb actually isn't on this list um and the reason for that is as i mentioned before it's still in beta so as soon as it actually becomes a fully uh qualified ga um that we can you know announce then of course we'll make it available out here as far as the dependencies are concerned so for now we're just going to be using spring data rtdbc library so that we can use spring data to basically help eliminate a ton of the verbosity that i was running into whenever i was doing that first implementation [Music] and lastly because i'm lazy i'm going to use lombok which is going to help me add or reduce some kind of some of the the scaffolding or some boilerplate code through some annotations and really just one annotation because i don't want to write one getter and one setter which is which is pretty lazy but i guess that's i guess that's what's happening now so i can go ahead once i've done that and i can generate it's just going to put that into my downloads folder and i want to um let's actually see i think i had already let's just remove this let me do this i don't want to name it okay so i want to drop that into r2dbc as this folder and that's just where i'm going to house this now i do have a completed version of this so if for some reason my live development kind of goes off the rails i will [Music] i will switch over to the completed version so that we can actually see an implementation of this but i think it's best to kind of start with nothing and then be able to add those pieces in real time so you can really see how easy and fast it is to get started with r2dbc within the application and by you know way of um you know just happenstance then once you've implemented then you get all the benefits of a reactive relational development environment so let's go ahead and let's close down some of this and i'm going to use visual studio code to create or open up my new folder of this so the project that i've created and i've placed in my folder i'm just going to go ahead and open r2dbc and if you haven't used visual studio code at this point it is just a free open source text editor code runner it is essentially it's been a life saver for me because you can use it for a ton of different languages they've got a ton of different extensions of course you can use a variety of other text editors or code editors but this one is pretty simple and it's free and it's got the dark theme so i like all those things from here i actually want to start by taking a look at my explorer window on the left hand side and of course it looks just like a maven project as you'd expect but i want to jump into the palm configuration file where of course i get a lot of the project information as far as the version the fact that i am using certain dependencies like spring boot i am using r2dbc spring data all these different things but as i mentioned before we weren't able to add the dependency for mariadb because it doesn't exist um inside of spring initializer as an available dependency so i'm just going to paste in manually for now on this uh dependency and you can find this out on the github um which you know i can kick over the links for any of that stuff for the project because the r2dbc implementation from radb is completely open source you can find all this information there as well so i'm just going to save that and that's really all i need to do in order to work with r2dbc with more edb and what we'll see is working with it within spring data as well and to keep things even simpler i'm really just going to work out of one file which is to do application now if you're writing a real application of course you would not be doing this because it doesn't make a lot of sense um and i'm sure the application would be much larger than this and it would get extremely frustrating but for our sake we are just going to be working out of one application and in order to save time i'm going to paste in oops i'm going to paste in all of the imports that i need so that i don't have to add those individually and i'm just going to go ahead and minimize that and that will allow me just to flow through and actually write the code without having to worry about whether or not i missed an implementation of some sort or an import somewhere but where i want to start so we've got an application that does nothing right it's just a regular spring boot application that at this point offers nothing really for us to do other than the fact that it will build um and then it just does nothing so where do we want to start well i typically like to start by setting up the configuration right so i want to actually use a the actual implementation of our mariadb rtdbc connector so in order to do that i need to set up configuration i want to do something to enable r2dbc repositories as something that i'm going to be using within spring data and r2dbc specifically spring data r2dbc from there i just want to create a private class that allows me to create a configuration by extending a an abstract class that exists within the spring data r2dbc library so i just want to call this r2 dbc can you know let's see dbc config and i just want to then extend [Music] abstract r2dbc configuration [Music] and then i just want to create a bean for a public factory creation so this allows us then to be able to let's see is this configuration i can't see if it's that's the one so now i just want to be able to essentially i'm creating a method that's now going to allow me to create my specific implementation of a connection factory and this is really the source of everything right because in order to connect to mariadb i need to have an implementation using a mariadb connector specifically and so that's what i'm going to be doing here so i can say connection factory and i want to then return this part um is going to be okay i want to use the multidb connection factory and i want to build in a configuration so the configuration i will use builder let's see if i okay from here then i want to [Music] use the builder object or the builder function then to be able to chain together some of the information so i want to connect i'm just going to connect to localhost i then want to establish the port even though it is the default port and i think that it i don't think it would have a problem if i just left it blank it's good to mention that the default port from radb if you're not aware is 3306 i have a user called app user [Music] and uh their password [Music] let's see so password one two three [Music] and i want to use a database to do so specifically the database i'm gonna be looking at as we build our application which i will mention what we will be building here let's see oh sorry that is actually called username all right so from here let's see oh yeah would help if i actually created a new object okay so from here now we have everything we need to actually establish a connection to marie db and the part that i didn't mention was that this application is simply just a to do application which is going to allow us to create tasks and those tasks simply have a an id a description and whether or not they've been completed so a very simple to do application or the beginnings of a to-do application but before we can actually do anything with our database tables which is just simply a single table called task we need to create an object that i can use to persist the information um or use the persistent information from storage and use that within persistent objects or models that i can you know be able to map to on my java application side so from there i then now get to use or justify lombok uh by using at data which is going to allow me to avoid having to create getters and setters i want to create an annotation for requiring args um for a new constructor so everything that's indicated that's necessary within this model want to require and that's because i'm going to create a method later on or a process later on that's going to spin up some values as soon as the application starts i then just want to indicate the table to then create my task object inside here as i mentioned i just have some very very small pieces of information which are the id and i have a non-null and the reason why i'm setting this annotation is so that i don't have to um or that it's required and it's the only thing really that i have to supply when creating a new object of type task then i can here and i want to add the very last one as i mentioned which is this field completed which tells me whether or not the task has been completed so at this point i have the connection and i have a model object much less verbose than what we were looking at and having to create manually using the mariadb connector for r2dbc but now i want to get into the meat of actually using this both the model and then the configured connection and in order to do that i'm actually going to use a repository so i'm going to call my repository task repository which essentially is just going to allow me a method for doing simple crud operations at the beginning and then being able to extend that with queries a little bit later on we'll see so i can use an existing class extended existing class out there called reactive crud repository and this is then going to allow me to specify the type of repository or the types of information that i want to be able to both you know input and output basically just use within this repository and then establish okay well what's the primary key data type on this as well which is integer [Music] that is all i need for this repository because as the name suggests it comes with all of the basic crud operations and specifically what we'll be using are the insert the update and we will be using actually i guess we'll be using all of them so i'll actually be using everything from creating reading updating and deleting so we'll get to see exactly how all that is done now in order to actually be able to use this let's see if i can minimize this use this in any you know kind of viable fashion i need to expose this to some kind of outside processing now i could just write you know some terminal base or console type application but i want to go ahead and expose this as an api which is why i brought in the reactive web project as well as one of the dependencies so i want to establish first a rust controller using a spring framework that allows me then to establish the api or the endpoint using request mapping i then want to just establish that if i want to hit it i want to call it api task and then from there i actually want to create a controller class called task controllers and this is just going to expose a couple of endpoints that are going to allow us to manipulate the data all the way through the mariadb implementation of r2dbc so i want to auto wire [Music] a usage of the task repository so that i can actually use the repository directly within this controller now this can come with any variety of layers right if you're writing an application you could be using a service in you know in between your controller and your repositories i'm just using it directly because as this is just a demonstration it's a very simple process of getting started but from there i want to be able to create a get method which is going to allow me just like it sounds to be able to get information eventually from my database but i want this to be able to be fully reactive right and so i want to then return a flux publisher object of type task i'm just going to call this git so extremely simple from here i'm just going to use my repository dot find all now this is part of the crud repository so this is a method that's already existing as an implementation within the spring data rtdbc library right so i use the reactive crud repository as i extended actually the reactive credit repository to create my task repository and is if i want to receive back my values that's all i have to do so that's my select star on task it's done i'm in fully reactive now that is something that is completely available for us to do but of course we don't have anything inside of this this table this task table we don't have any data inside of here so i'm going to create something very simply and i'm actually just going to paste this in here because it's not as important that this exists because this is just something we're using for demonstration purposes but i'm going to create a component right so this component class is something that's actually going to after construction or after essentially dependency injection does its thing with the task repository basically what this means is that this load method is going to fire when i or it's going to execute when i fire up this application so as i'm in developer mode i can just run the project it's going to kick off this method now what's important about this method is that i'm going to go and use a couple of different methods this allows me to cheat a little bit without having to create endpoints i can basically show off how we can use different methods that are available within the reactive crud repository and then we'll of course use the mariadb implementation of r2dbc to do things like delete so i'm going to delete and when that has completed right then i'm going to add in new task and if we saw before this is why i added the arguments for constructors and i added a non-null specifically onto the description because i'm just going to supply a couple of string parameters here or a couple of arguments that inside of this flux just and simply it's going to allow me then to create and map those to if we can get a cool little graphic in here it's going to allow me to take my string objects and it's going to allow me then to be able to create and map into new task objects from there i then want to take those elements those emitted elements of tasks and i want to save those into my database and of course nothing can happen with any publisher unless you've actually subscribed to it so i then have to say okay i want to subscribe to kick off this process and the summationist process then is that i'm going to clear out anything that's there and then i'm going to add three tasks right off the bat and this is going to allow us to be able to test our get method to be able to take a look at all these tasks so hoping that i have done everything correctly i am going to start the debug process and i can simply do that as you saw by going up to run on vs code and just say start debugging but certainly i could use i could build the package and i could actually run the the project using command line this is a simply just a lazy way of doing that same thing now from there i want to test this out i am going to use just because it's a little prettier to bring in here let's see if i can't [Music] so i'm going to bring in a something an extension and you could use postmate or postman or you could use curl in order to do the same thing i could probably just actually since it's a get request i could just go straight to the browser and enter this in but one of the things that i like to use is something called the advanced rest client which is an extension onto chrome just simply because it's so simple and easy to use but i want the formatting from the json that comes back from my endpoint so i've started the application and if all went well that means that my post construct method executed and i then was able to get tasks so if i execute my localhost 8080 which is the default port at this endpoint api task or sorry at this route for my api and then at my endpoint i specifically am just specifying that i want to get i use the get method that i establish with inside of that controller and we can see that i have three new tasks and because i have used this database a lot just for testing um the auto incremented ids are 67 68 and 69. now one of the cool things that we can do of course is that we could continue to add different methods but what's nice is that we can actually branch beyond just the crud the simple crud operations and we can actually add functionality into our task repository there's a variety of different ways that you can do this but just for kind of a quick show of what's possible as you can get started i want to add a new modify method and this is something that you an annotation that you would actually tag to anything that does an insert a delete or an update anything that's essentially modifying data you want to have this annotation on and from there i can simply just say okay well i want to query let's say update task set and i want to say the completed equals a completed value so maybe i want to be able to toggle a completed value for a specific task id so that way i can you know start to create maybe more of an application that allows me to actually manipulate this task list that i'm creating from there i want to return an integer value and this is going to tell me how many fields are affected or sorry how many records are affected by this query and i can then return a mono publisher value which is again it is going to emit zero to one element or one values um and it's going to be of type integer in this case because i'm returning account as i mentioned is is one of the capabilities of a result now from here i can just say i want to pass in integer id course and i want to pass in the completed version and this is then values that are automatically mapped into the query using named parameterization right so we can see we've got the colon completed where we're going to put completed and we've got the colon id so now all we have to do is really add in a way to use this we're going to call this just a put [Music] and don't judge me too much for my i'm going to get a little lazy on the implementation of this and i'm simply just going to add these in as request url request parameters so probably not the most secure thing or you know maybe not the best convention even for building an api as i'm just going to add id as an actual parameter but it's pretty easy to take a look at what it's doing and then i also want to add in my completed field because i want to say you know for a particular task i want to you know toggle the value somehow now from there i then just want to use my repository and i can see that now i have a newly available course method called update status that i can pass in id and the completed value right so here now we have exposed a put method which is going to allow me just to toggle the value so i'm going to rerun and i then am going to switch back to using my put or my advanced rest client to indicate how i want to use my put now here let's see let's go ahead and clear this value okay well we'll just put this in here we will put and i don't actually i guess i got to remember what the okay 70. i guess we ran it again so every time i run it again it deletes and re-adds so now i just want to toggle let's say task 1 which is id of 70. so here i just want to say okay for localhost 8080 api task for my put method i want to toggle that to true it then returns a value instantly of one which means that one record was affected and then i can confirm that by flipping back over to my git and i can see that i have able to successfully update the value that exists inside of my marie db database by using this api and that is really the extent of that demonstration portion um only because there is you know so much more that you could certainly do and dive into it um i do want to point out i will put this uh that's part of the problem with let's just say a new window um one of the things that i do have available um let's see [Music] let's see let's see an application i should probably have this book marked somewhere but i have created a fully fledged version of this application with all of the crud um you know kind of fleshed out and i am using a react.js front end and i have several backend options but one of them is r2dbc and i've gone through this exact same process but instead of putting everything into a single file i've used a little bit what i would say better conventions now it's all still in the same project but from here you can actually see full repository implementation just like i had before i have i actually use a controller just the same way here but i actually expose a couple of different endpoints which then allow you to actually create an application where you can do everything from saving or inserting updating deleting and selecting the values and it uses um obviously all the same tools that were that we're using now with instructions to be able to do this as well so it's a little bit bigger of a version of an implementation but the actual setup for this takes about five or ten minutes so if you just wanted to pull it down and test it out you could do that pretty easily it all comes with instructions inside of the readme of how you would do that as well as how you could set up just a containerized version of mariedb which is what i'm using now i'm just using a docker container version of mariedb on my local machine it's free and very easy to set up and it contains all the instructions for being able to do that um so and of course if you have any questions on this you could email me or twitter me tweet me or anything like that so with that i think that i will flip back over to the slides only and i don't think okay yeah because i only have one more to really go through which is this road map so as i've said a couple of times the r2dbc connector is in beta right now so there's still work of course being done on it we are looking heavily at performance and adding more capabilities specifically around things like data types like json geojson for geospatial data specific types for that and then pluggable types for things like json inet4 and boolean basically as the server mariadb server progresses then we're going to add support for that inside of our 2dbc at the same time but that is the gist of it so um i i didn't do a very good job of checking the question sometimes whenever i get into the code i i tend to just kind of to zone so if i missed any questions i really apologize about that uh okay cool um so uh let's see yeah yeah yeah sorry anybody feel free you don't have to ask the questions on you can ask them in chat specifically if you want to um but you can also um you know feel free to to use voice either way it works thank you thank you rob um yeah avon uh please ask a question yeah so it looks like okay so vaughn asked me a question it says does rtbc require the use of reactor um that is not a requirement of r2dbc but that is something that may be required from the implementation that is a so again the reason why the rtdbc specification is um so small really comparatively and really it kind of lets you do whatever you want to is that they didn't want to make implementation decisions um specifically for things like you know choosing a library like reactor or something like that um or you know options available within you know certain publisher subscriber implementation so no for r2dbc but if your question is do you have to use reactor for r2dbc with mariadb the answer is yes so hopefully that helps a little bit yeah um well i guess the thing is right we've got our own um reactive uh streams implementation in our platform and you know i mean i guess it's okay but introducing uh reactor to support maria db um is kind of a i don't know it's it's a little bit of a strange decision for us to have to make you know yeah so you know and this is i mean all of this feedback is really good for us too because certainly we don't want to you know limit anybody from being able to use it now the other thing is is that because it's still in development i mean there's still decisions that can be made as far as abstraction and things that we can do um to to make it a little bit more inclusive or you know flexible in that sense too um so yeah i i would if we want to connect after this um you know maybe we can see what it would take if you could use it um to to see exactly we can even connect with directly with diego who's the developer on there on rtbc and see you know if you have any input or you know direction advice or suggestions because this is certainly something that's new for us as well well i you know the thing is i could see if the driver is implemented using reactor but if the client could be a subscriber of any um reactive um you know streams type that would be pretty cool right so then we yeah yeah well i can just bring up the uh github you can yeah continue to talk through it but i figured i could just bring it up directly uh you might well yeah my own my whole understanding about the whole reactive streams thing is it shouldn't matter what any given publisher or subscriber is using it's just the interface that has to be honored and as long as you honor that interface it should be you know possible to support anything so to be nice to you know as far as i'm concerned you you guys should be free to use any kind of implementation that you need whether it's reactor or something else or your own thing but be nice to just use our reactive streams yep yeah yeah and yeah i can completely i mean i can certainly see your point on that i am personally i am a big fan of of being able to do those types of things too right whenever i write code i like to have the control and there's a lot of times i don't like to bring in dependencies for a lot of those things but it does look like here that they do have a dependency on reactor core yeah but again that doesn't limit what we may be able to do in the future so sure sure i mean this is beta that's good you know i'd be happy to meet your developer and talk to you more about it um the other thing is just wondering you're running a mac with uh mariadb in a docker container how does that perform is that is that actually pretty good or yeah so i use it from a development perspective um it works i mean pretty well i mean i again i don't i don't run anything crazy on it so um you know it's hard to tell but one thing i will say is that the new community server 10.5 now includes not only the traditional robased data storage that you would get you know even with mysql and mariedb in the past but it also contains a columnar database storage engine like natively and i will say that i put about 40 gigs worth of information so roughly about 200 million records and it performs lightning fast but you're running a mac the thing is my my uh my experience with both postgres and uh mysql is that it it's really slow on a mac you know because the docker um yeah and you know to be honest um i you know i'm pretty partial to mac coming from one of the things i think i mentioned before was that i you know i spent a lot of time in mobile development um so my os of choice has really just been mac os by default because it's the only way you can really build all the all the platforms for mobile devices all at once and so my relative experience with faster slow may i mean it to you it may end up being pretty slow based on the way i use it but for me because i'm not really comparing it too much to anything else it seems to be pretty snappy now comparing that to maybe you know you've gone to like putting that in um you know natively or kind of installing that directly i haven't done any kind of personal checks or benchmarking to see how much faster but from a development aspect if you're just wanting to try it out it spins up nicely and it's pretty snappy from the amount of information that i put in there now on the transactional side i can't say that i put just a ton of information it's really mainly been on that columnar side which of course is built specifically for large amounts of information so cool yeah i mean just a little off topic but a general question on your experience with that so thank you for yeah yeah thank you yeah i'm always happy to talk about stuff that i actually know about now if you get too deep into reactive i mean that's what i was telling alexi is that i'm still pretty new with a lot of that stuff so um you know i'm learning every day but it's it's pretty pretty awesome um you know some of the capabilities it seems like every day um learning something new and having to adjust you know content that i've created that is just completely wrong so it's been pretty exciting don't worry vernon arm will fix all of that stuff when the mac switch over right that's what they say well it's actually more about them i guess it's more about the file system right because if you're writing an internally in docker i guess you're writing to a linux file system and then it has to like thunk over to the to the mac file system and that's really the slow part so in the tests like in the test suites that we have for our jdbc database implementations just like inserting a few thousand records just takes minutes you know or you know it's just crazy yeah horrible yeah hey along those lines um your demo was you're using a reactive driver but you're also doing three records which is probably you know a single you know allow that many records in one in one hit on your reactive streams anyway do you have anything where you're really using back pressure and really pushing it back into marie and see how that so i i don't yet and so since this is kind of in the earliest but i mean that's a like the most valid question right is that okay this doesn't this example doesn't really besides you know being able to see how it's implemented and seeing something set up or scaffold in a way it doesn't really show the value of r2dbc but that is something that i'm going to begin working on pretty soon just because you know within future content in the book coming up um i think that's exactly right you have to have something that actually shows off the value of using r2dbc so unfortunately at this point i don't have anything um but i i just have to i've got egg on my face because i completely agree with you i think that i should have something like that thanks yeah and sorry that i don't um as of yet but i will i will try to whip up something because i think that that's really the best way to to show this off right is first start with implementing it but providing a use case of some sort where you can really start to see why you would why you would want to use it and really i'd like to have a use case where i use both jdbc and r2dbc in tandem or side by side um to really show that value off would be the ultimate goal and be able to write you know some kind of blog post on performance yeah i'd love to see something that kind of shows the the transition from legacy to reactive you know like a micro service it's interacting using you know standard you know sql threads and then okay here's what it looks like you know halfway here's what it looks like all the way over to a proper reactive micro service that's doing it right yeah i like that i like that approach too where you show like a transition as a as a form of steps rather than like all or nothing it's like here's how it's cuz because ultimately that's how you're going i mean any larger shop or any legacy project it's not going to be you know an all or nothing type of process right nobody's going to put any money towards something like that they're going to want to see it iteratively so yeah that's a really good idea here we go yeah cool any other questions [Music] uh i want to thank rob again for this great presentation and i actually think you know we really uh got into the setup all right uh we got into the basics so i think rob you know uh when you have uh uh the kind of demo of real back pressure use that would be part two so let's kind of consider it as a part two and you know we're definitely uh welcoming you back any time uh you'd like to continue the series because i think it's a really great introduction so we are looking forward to to you know uh next meet up and definitely you know happy uh the book uh you're working on the book so definitely you know looking forward to that yeah yeah thank you very much everyone for for having me and yeah i'd love to do a part two because as brian said i think that it's extremely important to be able to you know part of what i've been focusing on really with kind of my own ignorance up until this point has been just wrapping my head around all this stuff right and you know being able to get started and as i kind of move through these chapters it's crazy because i had i never really even considered writing a book i just thought well this would be a really good way to learn something as well and it really does force you to learn all of the nitty gritty um about something so it actually works out well from a timing perspective because i think as i go through that process um it's inevitable that you know the the examples that brian brought up i'm gonna have to use something like that um in order to be able to justify r2dbc right because otherwise the argument would be well i mean i could just thread out some jdbc right i could just create some small modifications why do i have to bring in and completely change the paradigm of what i've been developing up until this point so yeah i think it's great it called me on it too i mean i think that um i would love to you know even you know come back soon as soon as possible to be able to give a part two um just because that that puts the fire under me even more to uh to get an actual implementation plus i'm sure maria db would love something like that too because a lot of the information out on r2dbc has actually been fairly at that same level right a lot of the information you see is kind of this starter we really need that next level of okay well how do you take the next step you know or man i think a blog post or some kind of content where you talk about how do i move from legacy right java which has existed for decades applications which may be years and years old and using a particular style how do i move that into more of a reactive paradigm and what does that look like because you know that process isn't happening overnight all right yeah rob robert an important thing to consider is it's it's not just people writing applications it's like you know platforms or frameworks such as you know reactive ones for example we're based on the actor model so we're we're we have a you know our own interfaces over um relational databases over you know nosql whatever and as soon as we make like a a jdbc request our actor is blocked even though we're right even though we're fully asynchronous as soon as we interact with anything that blocks we're blocked and there's nothing we can do about that um i mean because ultimately something's gonna eat a physical threat on the processor right so and and so for from my standpoint r2dbc is you know wonderful um yeah from from the persp you know the basic concept of it cool yeah yeah i completely agree i you know and i think that um yeah i mean that part of the part of the things that i got into a little bit was this idea of um you know being fully reactive right creating a fully reactive solution because as you mentioned once you're blocked once um you know depending on how often that may crop up or you know where that exists is kind of this choke point can be pretty detrimental um and having this now i mean i guess if you were using a nosql implementation there have been reactive solutions for nosql for a while um and so this is really encouraging from a relational database side um just because you know it creates this in and i think that if i'm if i'm not mistaken there are a couple of different or at least at one time there were other specifications out there as well um on you know with r2dbc there were other ones like lesser known ones um and i don't know if that's still the case now but i think and you guys may know better than i but i feel like r2dbc has pretty much won out um with those at this point so yeah it's it's really exciting this is cool this is yeah i'm excited to join more with it with this group and learn more about it because i'm still kind of in the infancy of a lot of this stuff but it seems like i'm uh i need some back pressure my own because i'm drinking some of this stuff all right thank you everybody peter you might be muted i think you were saying something but i yes sorry i still can't i don't know if anybody else can i'm getting zoomed no [Music] we can't hear you peter he's unmuted from zoom but maybe on his side something is muted or sometimes my can you guys hear me yep yeah there you are okay great hi everybody um just wanna quickly comment um i've launched a small service one of our small micro services in production using rtdbc um cool it's primarily written in kotlin but we use project reactors kafka client and spring data with r2dbc since uh kotlin's or framework xposed doesn't support r2dbc yet we just use spring data repositories yeah it works pretty well um together and kind of i think foreign use had a comment earlier about interoperability so i also use kotlin flow which is another reactive streams implementation compliant implementation i use that together with the reactor kafka and r2dbc in the same stream even i convert them all eventually to flow and that part works pretty well so the interoperability seems to work pretty well and in this case i don't use mariadb but i use postgres using and the postgres driver also uses reactor neti client to at the binary level implement the binary protocol in a reactive way so they seem to work too good well together at least for me cool yeah very cool yeah it's encouraging to hear the usages of it too and if anybody would love to kind of contact me after this i would love to get everybody's contacts just because it seems like from reactive point of view you guys have a ton of experience i mean come from you know different backgrounds of using it too that i'd love to pick your brain as i kind of move to the process of learning more about it this has been you know this has been really encouraging [Music] all right thank you very much guys so really happy to start learning about r2dbc looking forward to to the next installment and uh i see you guys at the next video hey everyone thank you thank you thank you very much guys everyone