🔥 Mastering GraphQL & Spring Boot APIs | Real-world Example | @Javatechie

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi everyone welcome to Java Tei today we are going to explore an exciting topic that is graphql with spring boot by the end of this video you will have a clear understanding of what graphql is and how to use it in a spring boot app okay all right so without any further delay let's get started [Music] so if you have been following Java tii from the beginning then you might recall that already I covered the grab ql around 6 year ago this is the content which I was talking about however this content is now outdated over the past six year springboard has made it much easier to integrate with graphql by obstructing many complexities so now you can expose graphql API with just a minute instead of writing a lot of bulky code okay that's why I am remaking this video and even many of you have requested updated content of grab ql using the latest springboard version so that's the reason of preparing this particular content okay so let's dive into the topic first let's discuss what is graphql okay so graphql is a query language for your API which is developed by Facebook in 2012 and then it released as a open source in 2015 okay after 2015 onwards it was more popular in Industry because it provides a more efficient and Powerful way to ask for a speci speciic data from an API or you can say it allows clients to request exactly the data they need nothing more for example if you'll consider this use case let's assume this is what the data I was getting from some API or I'm exposing some API who will return these are the field out of that I have multiple client so one of the client can ask what he need how he can ask by preparing a graphql query by defining which field he need okay so once he build the query and give it to graphql now graphql will give you the desired response you can see here since client ask for the tag line out of this field he got the response as a tag line so if you have thousand of field or 100 of field just Define what all field as a client you need to process your business okay then based on that this particular client will give you the desired response or it will only give the response what you ask for nothing more okay so don't worry if you don't understand this example let me walk you through a real time use case to make it clear for you so let's consider we have an inventory service who expose an API with these are the field ID name category supplyer rate in price and stock this is just an example in real time you will find more than 100 field okay or it could be more now we have also different client catalog service sales team Warehouse team who want specific data from this inventory service for example catalac service wants only the name and price field but if You observe inventory service provides so many information however catac service only interested in the name of the product and its price he look the he want the response like this okay similarly we have the sales service or sales client who want to F only category ratings and stock information so that sales team can place an order so they are expecting the response like this only category and rating stock field not all the field from the inventory service similarly we also have the warehouse service who needs only the name of the products its category who is the supplier and available stock information to update new shipment okay and he expect the response like this now if You observe my different client need different set of data to process their work right but here inventory service giving same data to every client even though they don't want it which is really a bad practice isn't it now the question here how can you design your application to handle this use case cool there are two different solution I can think at this moment so the first solution you can ask inventory service to provide three different endpoint okay one Endo for catalog service one endpoint for sales team one endpoint for warehouse team okay like this inventory service can expose three different rest end point with desired field if catalog service need only ID and name he can build the response in such a way so that client can get only the ID and name now the second solution each and every client they can create their own D to map the response getting from inventory service for example I have client one here which is catalog service and catalog service only need ID and name correct he can create a dto with this field now irrespective of what data inventory service send back to the client they can have their own d to map that response again this is really a bad designing okay because if in future clients increased then inventory service will end up with creating the end point so there are new client came so then a different kind of response so we Define the Endo for their response okay and in other way if client will keep creating the dto for their new use case then again it will be a tight coupling between client and server isn't it so let's say client today need ID and name for catalog service tomorrow he need the stock and price correct then again he need to modify the D so in this way both server and client tied coupled with each other that's that's the biggest challenge here right then how to overcome this and design your application in such a way so that that it provide only desired field or response to the client what they ask okay so that is where this graphql came into the picture now how graphql help us being a client you need to specify what field you need as a response in the form of query then grab Quil is smart enough to extract those field for you so you can see here catac service need name price and ratings he can build a query with this particular field and grab qu will give the response back okay now in future if you'll add any field or if you need any field as as a client so just Define that particular field as part of the query then grab Q is well smart to handle such kind of use case so in this approach or using this grab qul you don't need to change any code either from the client side or from the server site to get the response okay so that is the reason grab Quil is more popular in industry and this feature is really out of the box isn't it cool let's start implementing the same scenario in action let's create a project from the scratch and we'll understand how we can play with the graphql in latest springboard version okay so let's create a project from the scratch go to the spring initializer then Define all the required field now just add all the required dependency so we need web dependency then we need Lum book we need grab ql also I want to store the records in our local DV which is my SQL I need jpa and also I need my SQL that's it the main dependency to play with graphql is spring for graphql can you see here all good now let me generate and import this project to the intellig idea so here is our project now if I open the pal. XML where using the latest springboard version which is 3.3.0 then we are using also jdk 21 and you can see the jpa and this is where the dependency we need to play for graphql web have dependency then my SQL lumo then it added the web flux for defining your test grab qu test fine that's it all good now let's create couple of package to to play with the product so that we can save the product and retrive we'll see the problem with the rest API then I will guide you how you can quickly convert your R API to grab Q Okay cool so let's create couple of package now let's define The Entity and their repo and configuration to just expose a red API then it will be easy for us to demonstrate further fine so create the entity then just Define couple of field ID name category price and stock the same field what we have discussed in our presentation then Define all the required annotation this will be my entity all argument Constructor no AR then data Define this as your primary key so just Define ID all good then let's create the repo you need to extend it from JP repo Define your model which is product or entity then data type of your product object is integer right so just Define the data type here that's it now let's configure the data source properties in our application. properties file and if You observe the structure here since you added the graphql dependency spring boot is smart enough and he created a folder called graphql can you see here inside this graphql folder you can add the schema as for the request and response that I will cover in a moment but once you will add the graph Quil dependency it will create a folder like this okay if it is not creating for you then you might not added the correct dependency then just open the properties file Define all the data source related properties also I want to change the port of my application 9191 okay so this is the data source properties this is jpa specific properties all good right so now let me start creating the service and controller so let me create a class then let me inject the repo here so let me Define a get or what I can say retribe method to fetch all the product from the DV from the inventory so public who will return return me the list of product just return it repository do find all okay now also I want to write a method to fetch a product by a condition so if You observe here we have category right based on category I want to filter out the group of product so I will also write another method get products by its category so products by category now I also need to define a method find by category then give the field here so we already covered multiple times how to define your custom method to convert it as a query find by is the prefix based on which field you want to filter you can Define that in a caml case so that spring data jpa is smart enough to convert that to the select query okay so let me create this method So currently we have just defined these two method to fetch all the record from the inventory and to just fetch a single or group of record based on condition fine so to do that first let's add couple of object in the DV on application startup so what I can do I will go to the main class then simply I'll will write a method public void dump or Define init DV I want it to run on application startup so what I can do I can annotate here at post construct then I will inject here the DV so first time we'll insert the record then we'll delete this piece of code okay so this is not the best part is to follow so just inject the repo again here now here I can add some hardcoded product object okay so just add it so this line is crying because of Constructor okay so see here if you check here go to the product we have defined all argument Constructor so it is considering all the field to pass so what I'll do I'll just Define The Constructor consider all exclude ID because ID will be autogenerated great okay fine this will run on application startup and will store the record to the DV so once it will be done we can comment it out fine now let's define the controller class for these two endpoint better let me copy the same name go to the package in the resource create a controller class just annoted your at R controller then just inject the service here this two method I want to execute so you can give the valid name fet products or get all products this looks good right get products let it be now instead of repo just call service do get products now Define The annotation of your rest this will be gate mapping so Define the root URL at theate request mapping this will also get mapping but I want to pass the category as a input so I will annoted here at the path variable okay cool we have Define only these two end point now let's run our app and we'll see the response was getting by the rest API then we'll think how we can convert it to the graphql so that it will give the response what I will ask okay so go to the main class just run it so application started If You observe here it also inserted the record for for us it create the table that's fine fine now let's go to the DV and just check it just refresh it we can see the table right all the record what we have inserted is present now let's go to the postman and try accessing the the end point get this is 91 91 so we are getting all the response in rest okay but this is what we don't want right if inventory service will expose all the field my client may not be interested few of the field from the whole response right my catalog service need only the product name and its price because I'm I'm a user I will use the catalog service to visualize the product available in Amazon or flip cart or Walmart then being a user I'm not interested to check about the available stock in your inventory system and uh who is your supplier I'm not interested for it being a user I need okay this is the product and this is the price if there is any discount if that field is there I also interested to look into that not all the field but current rest API is giving all the field as response which we don't want and we want to convert it to the graphql query so that only if I'll say I need category and price I will get that value okay that is what the use case we are going to perform now let's check our other G API we're getting two object again with all the field okay that's that's the genuine response we usually get from the r API but in our use case we don't want it okay now let's understand how can we convert this R to graphql because I need the desired response the steps are very simple only you need to define a graphql schema for your field then you need to play with couple of annotation that's it okay so the first thing go to your code okay so close everything go to the controller first so in controller if you are exposing it as a graphql query instead of RA API you no need to Define this The annotation should be only controller okay so query will read your method name I explain that how it works internally not at this moment I don't want to confuse you at this stage let's complete it then we'll understand so first thing you need to change the annotation to the controller then get mapping is not required you need to Define query mapping for all kind of retrival operation okay and here also you need to Define query mapping and since this is not rised API I want to convert it to the graphql to pass any argument you can Define argument annotation okay all good so now you might have a question on your mind hey if we are not specifying the URL then how can I access it simple right that is genuine but this is not R API this is the graphql and you want to access it through the query now where I can Define my query that is the simple step inside the graphql folder create a file called graphql file give the name schema dot graph qls okay so the extension was already taken so let me delete it I'll just grab K file schema okay fine now here based on what field you want to play based on the field which I have in my product ID name category price and stock because this is what I'm returning so I want to Define this field as a type so that when I'll ask you hey give me name and category of type you can give it to me so these things you need to Define in your schema it's not that you need to Define The Entity if you have a d which you are expecting a response there you can those dto you can Define in your schema okay so for example here I need to Define type which is product then what is the field I have field called ID up type ID then I have the field called name up type string I have the field called of type string like this you need to Define all the field currently I have these many field ID name category price and stock so I have defined it so one thing to notice here graphql don't support the double value so if you're using graphql you need to use the float for decimal value now that's the straightforward I have defined with this particular response I want to play or this particular object I my client can ask what field they need from this type now how can someone access this particular method because it's not APA it's a query so you need to tell here in the schema. graphql hey if someone is accessing this method then what to return or what will be the return value if someone is asking to access this particular query then what to do okay so how you can Define that again it's straightforward type query not end point okay now what is your method name get products so you can Define here if someone will call this particular method or if someone will call this particular query then return the product object okay now what is the other method we have get product by category make sure to define the method name as a query that's it you can Define any name here but whatever the name you will Define same name you need to Define as part of your query okay that is what the tricky part now this is the query I want to execute which will expect a input as a category right copy this value up type string and what it will return return it will return return array of product so this gate products will also array of product so that is the reason I have defined inside aray this particular method will expect the field as a category which I defined as a argument here if you see here I Define as a argument and up type this and this is are the expected now you have defined okay these are the two query I want to execute this two query will G will give the response as a entire field so now you have as a client you have the option from the type what you need okay don't worry we'll just validate this in a moment so far all good now let's run our application and validate it one second I don't want to run it so I want to comment this piece of code let's stop it just remove this okay or just better comment it for now let it be in a code now let's run our code so you can see here application started on Port 9191 But If You observe here it should expose one endpoint called grab ql let me search for that no it seems there is something wrong we have done I'm expecting it to the schema name the extension should be grab qls okay so let's refactor so directly I got the option from ID to create the file so I created that but let's let's see okay refactor it now let's rerun our app yeah so if You observe here loaded one resource in the graphql schema so if you make the extension to grab qls then it will consider it will load that resource and it will see here it started inspecting the file and it found okay okay it exposed an end point so to go to access the end point or to access the graphql query you need to go to the postman create new graphql just Define HTTP Local Host 9191 then just Define this graphql can you see here it immediately load the schema file and understand okay these are the two query defined by the user now user let's for testing let's go to the get products I want to execute this particular query but I don't want all the field to display rather what I need let's let's assume I accessing from the catalog service I want to see the product name and its price so let me comment others okay see here now the query will builds like this this is the query this is the method you have defined and you are telling here what field you need as a response okay now if I'll quy this can you see here what value I have received here only name and price nothing any additional field okay now for example let's say I want category asual let's say this is being accessed by the sales team then need name price and category now if they will execute this as part of response it will include the category field okay can you see here so whatever the field you need if you remember remember this field is coming from the types we have defined in our schema so if You observe here we have defined the types right these are the field is coming here as part of your query and if you need all the field Define that if you want to exclude any field just untick Mark that this is how if you have 100 clients and they need different kind of data they can build the query in in such a way to define the field what they need and they will get the response okay now let's try to access the other schema you need to provide the category first of all specify that you need all the field then what is your category let me copy the category one I will copy it from the DV this one Furniture right having two object so go to the postman enter the value now again while filter do we need all the field ID name category price and stock or you need only the ID or name and price name price and stock I mean anything you just need to Define what field you want okay I'm just playing with different uh field So based on your need you need to choose the field what you need can you see here I'm getting the name of the product price and stock even though in filter also you have option to Define what all field you need now if you're not interested to access it through the postman the way for rest API we have the Swagger documentation from the Swagger you can directly access it similar way for this graphql you can also enable the grab ql dashboard by just configuring two field in your properties file go to the application. properties file then here you need to Define spring do graphql dot graph iql do enabled equal to True Define what is the path you want to access this will be same I want to keep okay so this is for enabling fine now let's rerun our app and we'll validate now just copy this particular URL and let me clear this let me minimize this go to the browser simply type 9191 then just Define the URL can you see here whatever the two query you have it is already listed down here so can I clear this yeah so let's say I want to access this get products Define what field you need just execute it you'll get the response similarly check for this I'll copy this electronic you need to pass this value and what you need you need only the ID and name and price just execute it you'll see the response okay so the moral of explaining the graph Quil to get the desired response based on the field he will ask to the grab Quil he will give only that response rather than loading all the content okay so that's fine so if You observe here it's not showing here but let me see so so far what we have done is for gate API right or for the retrival purpose that's fine for retrival grab Quil can give me the response what I will ask for but is it possible to perform any save or update or delete anything on graphql using the graphql query yes we can do that so if you'll go here currently you are seeing only the query section right query means for the retrival purpose you can see called query but if you want to perform some create or update then you need to use the mutation okay I'll show you the demo in a moment so let's test this mutation scenario in action now what do we want to do let's let's say sales team wants to update the stock of a product okay so what they want to do let's go to the service now what sales team want to do they want to update the stock of an product in inventory system okay so what they will do so let let me Define the method public will return me the updated product okay update stock so to update the stock of the product first they need to get the product give the ID to face the product okay then what things you want to update the number of stock count what they want to update they can Define that now first let's get the product then they can just update the existing product with the new quantity okay that that's how they can add the or increase the stock count okay so to get that I what I'll do I'll just use first get the product repository find by ID get the product give the ID it will give you the optional it's good to handle the exception better let's handle it or else through or else through the exception what is that exception any exception okay so for now let me throw the run time exception this will give you the existing product now once you have the existing product with you what is the next step just update the stock count okay so existing product do set stock and the new quantity what is available just update that then just save it simple step get the existing product set the new quantity which sales team want to update in the inventory system just update that record and give it back to me okay so similarly let's try writing another method where what I can say uh Warehouse team receive a new U shipment okay so let's define Warehouse now how we want to design that so simply if they received new shipment they will check the current stock available and whatever the new shipment they received they will just update that stock count okay simple use case guys there is nothing to confuse I'll copy this I'll change the method name to receive again ID and quantity so first get the existing product object from the DV when I say DV get it from the inventory system then what you want to do in the existing product get the current available stock get the current available stock get stuck then just add the new quantity see earlier if it is 100 stock and Warehouse team want to update 100 more then the value should be 200 that is what need to be updated in the inventory system this is are the real time use case rather than explaining the hollow World fine now then again save and return it so the way we're fetching the and updating it similarly you can pass all the field to perform the create operation okay so this is part of the save and update fine now let's define the controller for these two method so just Define public return the product object okay so update stock now what it needs to update the stock we need the ID and we need the quantity correct so here how can you pass the input field argument or better let's change it to stock okay now you need to call service dot update stock give the ID and you need to give the stock so here also let's not confused change it to stock next go to the controller this is of type mutation mapping okay for create update and delete you can use this particular annotation instead of query mapping similarly let me write another method to receive the new shipment so what argument it needs it needs in ID and if You observe here what we have int quantity right just go to the controller just change it to the quantity and call the method from the service which is receive new shipment ID and quantity so no URL nothing as part of field what you want to pass you just need to Define at the right argument and then perform the way you do operate your DV related stop now once defining this annotation and defining this method it won't be available in your graphql because you need to again Define these two methods with its input in your schema file okay but not as a type of query rather you need to Define this as a type of mutation okay like this type now what is the method will be part of your uh mutation this one update stock what it is expecting as a input it is expecting as a ID and also expecting stock up type int okay then what it will return it will return a single product object fine so similarly we have another method that is review new shipment this is the method what it need as part of the input it need ID then it also need quantity in int okay so here we are telling to the grab ql hey I have two mutation to perform update and create these are the two each method will expect different input and this are the return type fine I mean it's just simple guys right in latest springboard version you know need to define the data feature and query resolver what we used to do earlier in in this current version you just need to Define okay this is of type query this is of type mutation these are the method this is what the input and this is what the return type how simple is this fine now let's run our code and we'll see whether the mutation is displaying in our um Postman or grab dashboard or not so it started now if you'll go to the postman new graphql and if I Define this yeah can you observe here see here in quiry which is retrive I have two methods in mutation I have two query update stock which will take these two ID and stock as a input and will return you these are the response after update the stock what field you want I want only the stock and ID you can Define that okay see the query it it is something similar looks like the method uh in Java right this is the method these are the input and this are the field I'm expecting now let's give some uh valid ID to increase the stock of that particular product let's say this one right laptop I have currently 50 stock available I want to I'm a sales team I want to increase the stock count to 500 or let it be 250 okay keep the ID one and what is the stock count you want to increase 250 after update what field you want to see I want to only see ID and the stock value okay just execute it you got the response with the field you requested for ID and stock now if you will check in the DV better let me trigger the query can you see here the value got updated okay now let's try to check the other mutation which is adding a new shipment okay so what we'll do just go to the postman now for example just check in the DV So currently this id5 desk lamp having 150 stock already available wherehouse team got 200 more or 750 more they just want to add this new shipment for this specific ID okay so go to the postman now we want to check this ID is what is that ID five give the IDE as a five and how many quantity they received in their inventory system 150 let's say they received 850 okay what field you need so I just need exclude the ID name category price and stock I need everything just send the request when I say send the request just execute the query okay the price got updated to the 1,000 earlier it was 150 we added the quantity as a 850 now let's validate the same in our DV can you see here the value got changed here okay so it does not matter whether you are performing the only retrive operation or any kind of crowd operation everything you can achieve using graphql and while performing the crowd operation you can specify what field you need as a client okay if I'll remove this category I will not get that as part of the response so in this way your server and client both are losely coupled with each other so if in future client needs more field he can simply send as part of the query like this okay so that is what the power of graphql he is smart enough to collect the field you need from the whole response okay so this will be always recommend recomended if you have multiple clients and they need different data set as a response rather than create a separate dto or rather than create a separate endpoint it's good to use the graphql so in this current example we only covered query mapping and mutation so if You observe here there is another annotation called subscription mapping so if you guys are interested to know about the subscription mapping do let me know in a comment section if you have any doubts or if you have any concern please feel free to raise your voice in a comment below that's all about this particular video guys thanks for watching this video meet you soon with A New Concept
Info
Channel: Java Techie
Views: 10,410
Rating: undefined out of 5
Keywords: spring boot graphql, javatechie, spring boot, graphql
Id: GJc36OKFQ_M
Channel Id: undefined
Length: 49min 48sec (2988 seconds)
Published: Fri Jun 14 2024
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.