How to Build A Rust Backend with Actix Web and SurrealDB (Full Tutorial)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
all right welcome back everyone so today we'll be learning how to build a back end using rust right via actic web as our framework and seral DB as our data layer all right so let's take a look at what will be building today so over here we have Postman okay I'm using Postman to demonstrate uh visually right how and what we'll be building as well right so over here we have a get endpoint to get a list of pizzas yeah so a very simple endpoint and we also have a post endpoint for us to buy a pizza so for example if we want to buy a double meat pizza right and we're going to call the buy pizza endpoint using the post method Right double meat pizza and if we go back to the list of pasas right you can see that okay we have our double me pza over here right that we have just added and bought and of course we have a patch endpoint yeah to update a pizza if and when needed to right so this will be what we are building today and let's jump right into it all right so for status we need to create our Russ project using cargo right so cargo new let's call this rore for back end all right so that was pretty fast and let's go into our newly created project so CD R back end all right so by default right usually we have our cargo. to and our SRC Source folder all right let's clear this okay so we'll need a few crates in order to work and continue on this right so we will do cargo and that okay so the first create obviously we need ax web right that's our framework that we are using right to build our back end okay and we also need Json right because we'll be returning the results in Json format right we also need s right to enable serialization and the serialization right it works with Json as well all right and of course seral DB as our database and we need uu ID to generate unique uu IDs for our pzas all right we also need valid dator this will help in validating the data sent to our backend right to ensure that the right type of data is being sent yeah it will be helpful and we'll talk about this later in a video right and we also need Asing trade yeah this will also help towards the end of the video we'll talk more about this but it will help us uh in terms of maintaining your code yeah uh in the longer run uh especially if you want to use traits for various strs in your Ras back end yeah and lastly we need derive more uh which works with Asing tra as well right so these are the few crates that we need in order for this back end to work right so let's install them and we are done all right so let's clear them and let's do a simple cargo build to ensure that by default we can build this first even though it's an empty rust project for now right all right so now that we have done compiling and building our empty rust project right it's time to open up Helix and jump right into the code all right so we on now in Helix and we are now looking at the cargo. to file so once again if you are coming from a typescript or react envirment or background can think of this as the package.json equivalent yeah okay so we need to make some changes to the dependencies here especially for sech and validator yeah because we want to use the traits provided by them yeah and to do so we need to modify how they are imported here right so we just need to declare the version and include the features Yeah by using derive right so that you can use the traits with derive right so that's for thir and we need to do the same thing for validator as well right so version equals to and features equals to derive all right save that and let's Build It Again by going back to our terminal and let's do another Caro build and that was fast because we didn't change much this time yeah so let's clear that all right now let's go back to Helix all right so now we're back in helix and since we don't have any issues compiling it's time for us to write the first version of our end points yeah so let's go to our main. RS right main. RS you can see right now it's very bad bones right and all it does is PR hello world okay but let's move this down because we want to write a few end points using actic web all right so to do that first first we need to import actic web obviously yeah so use all right actic web right so with actic web you can do something like this get and we Define the endpoint routes which is pisas yeah which is what we saw at the start of this video right and because okay we are dealing with a web framework here right this has to be asynchronous right asyn function okay and we're just Define the function that will be map today slpas endpoint via get all right and responder right so this is the default interface provided by ax web yeah so by default right this is what it could look like like yeah a very Bare Bones version right so all it does right is just to uh return or respond right with a 200 okay status right with the message P available yeah so it's a very simple endpoint for now right but you can see okay because we need to import this as SP right same thing all right uh let's save this okay so now okay this endpoint is not going to work because we have not attached it and we have not even defined right the server for our back end to run on using actic web right so let's do that next okay okay so to do that we'll need to modify the main function here all right okay and we're going to do that that once again using actic swb right so you might notice that uh with the endpoint here okay we using this hash square brackets all right so this is a form of uh macros or macros provided by actic web all right uh micros Ras deserve its own video yeah so there will be another video for another day yeah okay so but okay if we continue here right so this this what we're doing here is to tell atic web that hey this is the main function to start the back end all right and of course once again this will be async function and and we'll just return a result all right so once again this is also something we have to import from uh acting s yeah as usual all right and let's remove this okay we're getting some errors but it's fine because we haven't made the necessary required Imports yeah so it's fine okay we'll get to that once we finish the code for the main function for now all right so over here we'll call HTP server using actic SW once again notice how it automatically Imports it yeah okay we'll create a new HTTP server right and you create a new app once again provided by actic web right so this an actic web web yeah right we'll initiate and create one a new one and we'll call the do service function provided once again by I think it's where okay and we'll pass in get pasas right the function that we just created right just above the main function yeah all right and we'll bind this HTTP server to our Local Host yeah so that will be 127.0.0.1 yeah uh and if I remember the part should be within it as well right okay and we'll do run and oh wait since this is a async main function right uh let's save that and let's remove the additional brackets save that all right so this is a very simple back end but okay let's run it okay by going to our terminal here all right so let's go to our terminal here and if we do cargo run okay now the back end is running and let's go to our Postman right and if we do HTTP Local Host SL pasas right and if we hit enter right you'll see that right just above my head right you'll see pizzas available yeah so that is how fast and simple you can get a backend up and running although this is just a starting point with our first get endpoint yeah so let's create two new end points for post right for buying a pizza and for patching updating a pizza right an existing pizza right so let's go back to Helix all right so over here we're going to create two new functions yeah so one for buying a pizza and one for updating a pizza right one using post and one using patch right so let's do Post first yeah right so remember the endpoint was buy Pisa all right so once again uh an synchronous function by Pisa right for now we are not returning a Json yet so we are just returning a 200 status right so for that we can once again using the HTTP response yeah provided by a web right so buying a pizza all right and same thing for patch yeah patch you do update Pizza okay so for patch it will be slightly different because we want to know which p pza to update for uh which is why over here okay you notice that we are passing in something interesting right which is the U ID of the pizza right we'll get to this later in the video okay but for now this will be update Pizza all right and once again we're just returning a simple 200 response with a simple string yeah so updating a pizza okay and of course we need to let our server know about the new two end points that we just added right so because of that we need to call the service method again on our app right so over here let's do dot service by pza and service update pza right so this will attach the two new endpoint handlers routes to our HTTP server right once again powered by ax web save that and let's go back to terminal okay and let's stop the server uh let's clear that uh so you notice that whenever we are making changes to our back end we have to stop and start the server which is kind of annoying yeah so instead of doing that and running cargo run every time right we can do cargo watch right so cargo watch and run yeah so what cargo watch does is whenever we make a change in a code for our Ras backend right this will automatically rerun and recompile right so think of it as the backend version of Life a hot reloading for whatever JS framework you're using for your front end all right yeah so if we go back to post man now yeah and let's create another tab here let's do post all right let's once again let's call our Local Host endpoint but this time we're calling by Piza and you can see on top of my head we're getting buying a pizza right so that's one of our new end point and of course let's do the same for patch but this will be update pza all right send right you'll notice that it says 44 not F and that is because okay we need to pass in the U ID as well right so uh let's pass in a random U ID and send okay there we go yeah updating a pizza all right so we have added three new end points yeah to our actic web back end all right so usually for post endpoint right it will take in a body right of information uh which currently our endpoint our post endpoint at/ bypa doesn't yeah so we have to modify it to do so yeah so let's go back to H Helix all right so we are back in Helix yeah so in order to take in that body of content we have to create a new struct C by Pizza request yeah because we are buying a new pizza right and we put it in a sub folder called models right and Ina called p. RS right so for that obviously we need to create a mods. RS yeah to let Russ know that hey we have have a subfolder of models yeah so first thing first right uh let's create the model folder and create our p. RS in it yeah okay and let's take a look in p. RS uh let me just write a comment this will be pizza. RS save it okay right and we also need to create our model do a mods. RS yeah this will let R know that we have the model do uh the model sub folder right model. RS and over here we just say pop mod Pisa because we have a pizza. RS inside the model sub folder all right uh for now we'll save this and let's go to p. RS here and okay here we can create our buy pizza request yeah okay so because this is a body of content that takes in Json we need to derive yeah from serialize and D serialize provided by S all right and because of that let's go to the top and we'll import s thisiz and serialize right so use set right the serialize comma and serialize and of course we need to put them in curly brackets all right and of course we want to validate what is in the body so with that we will use the validator create okay so use validator same thing uh this will be validate all right and derive will derive validate all right uh the serialize and serialize right so this is for our buy pizza uh requests yeah so buy pizza [Music] request and in it we want to validate the Piza name yeah so basically we have a pza name that will be passed in either from the front end or from the user right so for now this will be just a simple string okay but we want to validate it using our validator create and we want to say hey it must be a length it must have a minimum length of one if not we'll [Music] say text or name let's say pizza name required all right and let's save this right and that's it for now for pizza. RS in our moders subfolder okay let's go back to our modus file and over here we need to let Russ be aware of our new buy pizza request so we'll say PP use Pizza by Pizza request all right save that all right and lastly we need to let Russ know of the assistance of the new model uh folder or module yeah so let's go back to mean. RS and at the top we have to say mod models all right you can see that the prompt is out yeah so save that and now we need to go back to our by pza endpoint to modify it so that we can take in the name of the pizza so over here in buor pizza right instead of being it empty with no arguments or parameters we'll say body Json yeah because you want to take in Json all right and this will be by Visa request all right so it's that straightforward okay now of course we want to validate the B body of the Json by Visa requests yeah so this is where the validator create comes into play so we can say let is valid you can call if valid or not right equals to body dot validate all right so and we'll match this right so depending on the results right we'll return different responses all right so we'll say okay if there are no errors if there's a pizza name provided okay and of course we can retrieve Pizza Name by going into body right uh let's do pizza name do clone okay there are other ways of doing this but for now to keep it simple we just clone it okay and okay we just return up HTTP response once again for now yeah okay will say p enter s pza name and if there was an error with validating right we'll just [Music] say pizza name required all right and if we save this right you'll notice that there's an error here uh because we have not imported this yet right yeah so let's do that now right so we'll say use create models Pizza buy pizza request all right and save that right same thing for for validate because we have not imported our validator create yet so let's do use validator right validate and save all right and we also need to use our format method right so that this Pisa name will use our Pisa uncore name that we just got button right so save and now let's go back to postman okay now if we go back to postman here and if we try to do another by pizza right you'll say content type error okay because we have not passed in any Json yet so let's do that now all right and if we pass in an empty Json right notice that that you'll say missing field name pcore name yeah so this is the uh validator create at work yeah so you don't have to do any manual validation yourself yeah so that's how powerful and useful the valid dator crate is yeah so over here we need to pass in pizor name and let's say triple cheese pizza for example all right and if we click send again right you'll see that it says Pizza enter is triple Chase pizza right just right above my head yeah so that's how you can take in the body of a post request all right now if we look at our patch endpoint with the slash update pizza right right now it doesn't make sense at all because we are not able to get the U ID from the route yeah so let's change that so let's go back to Helix all right and we're back in Helix so let's update our update pza function over here so that we are able to capture and do something with this C ID which is part of the route all right so let's modify this function signature to look like this right so we need to give a name uh let's call this update pza URL and this is a path provided by EIC right that should import it and of type update Pisa URL which is not something we have created yet but it's fine all right so if we save this now all right Ras will throw an error because we have not created update Pisa eurl yet yeah so to do that let's go back to our p [Music] RS in our model file okay and let's once again same thing we are going to use validate deserialize and serialize right because we want to do calization and we want to leverage on the valid dator crate yeah so this will be update pza URL and we'll just have a uu ID in it all right save that okay and also we need to go to model. RS yeah so this is so that Russ knows that we have a new struck in the form of update Piza URL all right and we can use it in our main. RS yeah so now that we're back in our main. RS okay you can see now we can import it right so let's go to the top and over here okay we can put a bracket and we can put update pza URL right save all right and you notice that okay now okay we need to finish the rest of this update pza function so let's do that now okay so to get this uu ID out from the route yeah okay all we have to do is say let your ID equals to update uncore Piza _ URL dot into inner all right dot U ID all right let's save that first all right and the puth is not using the right path uh uh let's take a look so this is actually not the right puff we should actually just use puff yeah we'll do oh actually web puff yeah all right yeah so now if we all right so now if we try to do an enter into in know we should able to see the U ID yeah so that's provided by our update Pizza URL type yeah all right and here we can say format updating the [Music] pizza with this U your ID all right uh let's close that bracket as well save that all right and now let's go back to post B and check out what has changed with our patch function all right so now we add our patch function all right at Postman so for example if we say 1 2 3 4 5 6 7 8 9 0 right calling our update pza function right you see above me now it says updating the pizza with 1 2 3 4 5 6 7 8 9 Z yeah so that's how you can get the U ID from this route right so for example if you want to update a specific object yeah this is how you could do it all right at the moment our three end points doesn't really do much because it doesn't really save the data persistently yeah so this is where serial DB comes in all right so we have to install serial DB uh using this command so let's go to terminal our terminal here all right and we install this command uh let's Okay using this command here curl Proto uh using https protocol right so that's just the SSL [Music] version and uh URL so I will copy and paste this command Okay as the top pin Command right so don't worry about that yeah okay and we are using the nightly version because there's a bug with the current uh latest release version so we are using a 90 version that fixes that bug all right so this is the command that you can use to install seral DB yeah okay I already installed it so I will not reuse this command okay let's clear that and to start a Serial DB server or to check that you have installed serial DB correctly okay we can just say sural version right you can see that okay we are using 1.0.0 and what not right that's the version of our serial DB all right and to start a seral DB server locally okay uh first let's go into our Ras backend folder yeah because we want to create the persistent DB here right so let's clear that and and to start the serial DB in persistent mode we'll say seral start file uh we'll give a name to the persistant DB file let's call this Piza shop DB all right and we're passing the username and the password right so the username and password is up to you okay but for this video we keep it simple so we name it root and root yeah so start okay you should see something like this yeah so to test whether Ser DB is running and up okay we have to go back to Postman yeah let's go back to postman and over here if we do a request for Port 8,000 that's the default Port yeah for Ser DB and we say slash version right if the serial DB server is up and running all right we should see this right the version of seral DB as the response yeah so you can see that it is up and running all right all right in order to connect to the seral DP via our rust backend we will need to create a database connection through it uh which is why we are now back in Helix right so we're going to create a new sub folder called DB yeah yeah and which is why we'll need a db. RS so let's create that right now yeah uh so this will be db. RS all right let me just save that all right we will also create a database. RS file in this new DB sub folder right so let's do that real quick okay so DB database. RS yeah so if you take a look at the bottom left corner here yeah you can see the name of the file database. RS in our DB sub folder all right okay and in here we will import our seral DB crate so use seral DB okay and okay we use the engine from DB okay and okay and the client as well yeah and of course the web socket all right uh we also use the root or the authentication root and we also use the eror provided by seral DB all right okay and let's do a derive clone okay and this is where we'll create our database stru okay uh we should have a Serb client in it so this client is our seral client okay so back C okay and we have a name space uh that will be used by serial DB okay uh this will be a string and the name of the database once again a string right let's save this all right yeah so this is just the definition of the strp so we also need to add the implementation for this new strp yeah so let's do that with the implementation of this database okay and we just need one simple function okay which obviously is going to be asynchronous yeah and we'll call this init yeah uh and we'll make it return a result of itself or an error I mean if it fails yeah all right so first we initialize a client a Serial DB client so we'll say let client equals to seral new okay and web soet okay and because we are testing on local horse this will be 127.0.0.1 okay and on the port 8,000 right so that's where our CB is at Port 8,000 by default yeah okay and of course we need to await yeah since this is a synchronous yeah right and we just do a simple sign in right using the authentication rout okay with a simple username of root okay remember the comma we entered to start our Ser DB server yeah uh which included the username and password yeah so this is just for testing and demo purposes okay but in real life scenarios yeah you better change the username and password all right okay we're going to do an await here once again for the signning function okay and we'll call the use name space function here we just use the Nam space seral this is up to you what you want to use okay and we'll call it use DB function uh in this case we call DB pzas yeah and of course we need to await uh usually I wouldn't do this but uh to keep this short we'll just do an unwrap yeah so the program will Panic if there's an error in connecting to our serial DB all right and we just return the database okay once everything is okay yeah so name space uh we just be a [Music] string uh from seral yeah and DB name you guess it will be a string from pasas all right and let's save that okay so there will be some errors because we have not defined the modu for this yet all right all right and in our db. RS okay we have to let Russ know of the existance of the new stru right so let's do that so pop mod the database yeah and pop use database database yeah so let's save this right you can see that uh right you can see here at the top there's an error it says file not included in module 3 yeah that's because we have not made uh the program right or rather we have not made Ras aware of our new DB module yeah so let's go back to main. RS and at the top we'll say mod DB all right okay and of course we have to say use create DB database yeah so save that all right and now if we go back to database. RS you'll see that the error it's gone so in our DBS yeah we can see here we are making R aware of our new database struct as well yeah all right so now to connect to the DB we need to go back to main. RS to create the connection yeah so let's go back to main. RS here and inside of the main function yeah before where we create our new HTTP server here all right okay we have to create and initialize a new database yeah using the new database struct that we just created yeah in database. RS so we say let DB okay we just name it DB short for database right it goes to database you can see that the prompt right the auto complete is out right so we call the init function yeah okay and we'll call call do await and okay we do a simple x yeah so this will get printed out if there was an error connecting to the database and we'll say let dbor data equals to data so this data will import from actic web so this is pro provided by actic web as a way of wrapping around your data layer so that you can couple it with your HTT HTTP server below right so we'll say data new and we just pass in the DB right it's as straightforward as that right and once we have done that we can just do over here do app data yeah you can see here uh the information about this function yeah basically we will just pass in thebore data here right so save that yeah and okay you'll see that we have an error and that is because right DB un data yeah over here it says that we cannot move out of DB uncore data which is a captured variable in a closure yeah right so to resolve this all we have to do is call move yeah over here and just clone it right save that and the error is gone yeah so using clone here is just one of the ways to resolve this but there are better ways but we're not get into that for this video yeah so in addition to using actic web data wrapper to wrap around our database our Serb database this will also in turn allow us to use seral DB in combination with our endpoint routes yeah all right now before we move on to leveraging on seral DB right in the endpoint rout that we have created okay we'll first have to create a new struct to act as the model right so let's go back to p. RS and create a new struck called you guess it Piza all right so we'll call this Pizza yeah and of course it needs to be validated right it needs to be serialized and deserialize B yeah right so we'll do the same thing as above with our update Pizza [Music] URL okay yeah and maybe I'll just put in the bu for just for testing purposes yeah and to keep it simple simple for this Piza stru we just have two attributes yeah so one is the U ID first to keep track so this will just be a simple string and we will just have the name of the pizza all right once again a simple string yeah all right so this is the stru for our pizza and now we need to implement it right so let's do that right away okay so we just have a simple function called new yeah which will help us create a new pizza yeah using the strp All right so we'll just take in a new ID and the pizza name and we return a pizza all right so this will be just be Pizza new ID Pizza name all right right right it it is as simple as that yeah so basically this new function here will create or will allow us to create a new pza okay whenever the user or the front end calls the post end point right over here right by Pizza yeah to do to do so all right so we'll use this in conjunction with our Piza stru yeah all right so if you're coming from a nodejs background you might be familiar with ORS yeah uh so take for example squiz yeah okay so over here we are not actually using an orm okay but we are directly interfacing with seral DB yeah so say for example if we wanted to get all pzas from serial DB yeah uh we could create a new function in right the database. RS yeah uh and over here in the implementation for database okay we can say pop aing right get all pzas yeah right this will require itself and we return okay sum or none of a vector of pizzas yeah so that's is what the option is for yeah right so hence uh this is why we need the Piza stru as well all right okay so here it's quite straightforward we just do a simple select of all the pizzas from our serial DB so we'll say let that result equals to self yeah dot client so this self is referring to our database struck and the client is the seral DB client in it yeah so remember our client here all right okay let's come back to this and we'll do select right and okay we pass in pza right dot AWA since this is asynchronous yeah and we'll do a simple pattern matching here yeah so match result all right and since this is using an option so it's going to be okay right all right since this is using a result is either okay or error yeah all right so this will be using all pasas okay and we say some all pzas all right and if there was an error okay we don't need the results so we use an underscore to let Russ know that hey ignore the results here and just return none all right right so save that and you'll notice that Russ is automatically able to conf that hey this returns a vector of pzas yeah I mean provided that there was no errors all right so now we have this get all pasas function yeah we can call this new function in our get pisas endpoint all right so let's jump over to there right over here in our main. RS right here we update this function over here and use our seral DB right to call that function that we just created all right so in order to do that we need to pass in the DB itself right so over here we say DB data yeah all right and we'll say database okay and we're going to remove this line right remove move and we'll say let pasas equals to db. G okay you notice that the new function that we just created Gore allore pasas is now available for our usage and we'll say dot await yeah and we'll do a simple pattern magic here so we'll say match [Music] pizzas and if we have found some pizzas yeah okay we'll just return for now yeah and okay response all right do body and because we want to show the results okay we just do a simple format all right so body format okay and okay we just want to print it out right so found uncore pzas okay but if we didn't find anything okay we just return an error okay using our HTTP response a simple ER string that is yeah so save that all right okay and let's go back to pulse B to try out the endpoint now yeah all right now if we go back to post B over here and you see that okay we're getting an empty Vector as the result yeah when we try to use this get/ pizzas endpoint again because there are no pizzas in the seral DB yet yeah so next let's add a new pizza to it all right so let's go back to Helix our Ras code yeah and let's go to database. RS which is where we at right now and we're going to add a new function here and let's call it add pza right so once again pop Asing function atore pza same thing we need the database struct itself yeah and this time we need okay we need the new pizza that we need to add to the database yeah and of course we want to return the result of the newly created pizza right so we use option for that all right and we'll say let created uncore Piza equals to self uh let's do do client okay we want to once again use the serial DB client in our database stru okay and we'll call the create function yeah provided by the client all right and over here this will be Piza yeah and we just pass in The UU ID of our new pizza all right okay we'll call clone here since we are not using any references for now yeah do content and we use the new pizza yeah as the content for the new pizza in our Ser DB and because this is async Let's do an await and okay we'll do a simple pattern matching to determine if this was successful right so if it was right we'll say created and we just return the pizza yeah okay if not okay we just return empty all right so save all right and let's go back to our slash bya post endpoint yeah so that is in our main. RS okay so we're going to modify this function over here yeah so that we can call that newly added atcore Pizza function all right so let's do that real quick okay so we have to modify once again the signature of the function yeah because we need the data from the serial DB all right so once again we will do uh DB yeah data database right so this is similar to what we did for our get pizza's endpoint yeah okay so of course once again we need to validate it yeah same thing here right this line validates it yeah same thing okay okay but when it is different is now okay we need okay to create a u ID yeah that we will use as the unique identifier for this new pza so we'll say let mutable buffer goes to UU ID yeah so that is the create there we install yeah at the start okay and let's make sure that this is imported correctly okay let's take a look at the top okay most likely we need to import it okay so we'll say use you you ID all right okay and back here yeah can see now okay we can use this yeah uh let's remove this okay and so we'll say you U ID u u ID all right and code buffer all right so this will give us a mutable buffer where we will be able to create our new U ID right so newcore U ID equals to U ID u u ID okay we'll use the version four generator to create a random your ID uh all right and we call the simple function here yeah and we'll encode it okay and all in lower case right hence the encode uncore lower right and we're passing the reference to the mutable buffer that we just created all right and let's create a new pizza [Music] here okay using DB do addore Piza right which is the new function that we just added to database RS yeah okay so over here okay we'll create a new pizza using our pizza stru yeah so Pizza New remember that function yeah okay we'll say string from New _ U ID okay and we also pass in the name of the pza so pza name yeah and we'll say dot await yeah since this is an asynchronous operation yeah okay and we'll do some once again some simple patter maging right to check if this was a successful operation in creating the new pizza in our ser DB yeah so mashore new pizza right let me just scroll up a little bit okay and if this was successful okay we'll just return uh simple HTTP response for now okay okay and we'll use format to return the results yeah so over here we'll say created new pizza okay and we'll print this out so over here we will just have to pass in the created pza yeah okay but if there was an error okay we'll just print out some other random message okay I guess we can do error buying Pizza all right so we can do that all right okay and let's remove this since this is no longer required yeah all right and let's save this okay this is because we have not imported pizza yet so let's do that real quick yep okay so to fix this okay all we have to do is go to our model. RS yeah because here we have not made it public yet so PP use Pizza Pizza yeah right similar to what we did for our buy pza request and our update Pizza URL all right and let's go to main. RS and over here okay we just need to import it yeah uh which is what we can do at the top here right next to update Pizza URL we just need to import pizza right as well save that okay and the error should be gone all right okay so now let's go back to postman and test this out yeah so let's go back to postman over here to our post end point right slash by Pizza okay over here let's make sure we change the body type to raw and to Json as well okay and if we just pass in an empty body you can see that the valid dator crate is working is Magic right it already tells you that hey you need to give us the pizza name yeah so let's do that so we'll pass in the pizza name [Music] here right above me yeah and let's start with maybe triple cheese pizza all right okay so watch what happens when I click Send yeah so now it says hey you have created a new pizza with this U ID and the pizza name yeah all right now let's go back to our G endpoint at/ pizzas so now okay remember previously okay when we use this endpoint we got them back an empty Vector because the database was empty okay but watch what happens when we click on send again and now okay we have our first Pizza in the database over here yeah okay so what happens if we add more pizzas right using this post end point here yeah so for example we can say maybe uh let's do uh Meat Supreme Pizza for example yeah send okay so we added a new pizza to our seral DB and if we go back to our get and Point again okay now you'll notice we have two pizzas right okay as shown by the response here all right so with Russ there's no such thing as now okay but that encourages you to think ahead in terms of what possible errors your program could get right especially at runtime so for example for our three end points that we have created here yeah we could get no pizza when we try to retrieve all of the pizzas from the get end point or that could be an error in creating a new pizza or updating an assisting Pizza yeah yeah so to cater for those possible errors yeah we're going to create a new inam right shot for immigration yeah called Pizza error all right so to do that let's create a new error do r press uh this will tell r that we have a we have an error sub folder yeah right and in here let's say Okay P mod a public module pcore errors okay this is not creat yet we'll create it later uh which is why when we are typing this Ras will complain yeah for now it's fine yeah all right so let's call uh inam pza error right so so save this all right and now let's go back to main. RS to let R know that hey we have a new module yeah uh called error all right so go back to main. RS let's go all the way to the top and over here we can say mod errors all right yeah so notice that it gives us an error uh it says hey we cannot find a module far errors. RS or errors SL mod. RS yeah all right so instead of that we can just say mod error yeah because since we name our file error. RS yeah instead of errors. RS yeah okay so now we actually have to create a sub folder called iror all right and we'll create our pcore error in it yeah so this will contain our new inam pizza error here all right so we're going to use derive more here right so this will allow us to derive a very commonly used trade such as display yeah uh which you can think as the user version of debug yeah which is commonly used for outputting the format all right uh so we say derive debug display all right and here we will declare our new enam okay which we mentioned just now so it's pza Error so there are few scenarios here so one possible error yeah which is no pizzas found all right uh we could also have a failure in a failure in creating the pizza so that would be Pizza creation fail layer and maybe no such Pizza found yeah for when you're trying to update and existing Pizza all right so now if we go back to our error. RS right you'll see this error here yeah because we have not imported this correctly right so let's see Pisa _ errors yeah so have we created that Piza uncore errors right so it's actually Pizza uncore error yeah so the naming is very important yeah so you can see pcore error is correct so save that right and the error should go away because now the RAS compiler has found our new pza uncore error module all right right same for in our main. RS yeah with the new error module so now to make this new pizza error in them useful and work with atic web yeah we need to import and use atic web at the top here so first obviously we need ethics web yeah all right okay let's say we need the hater content type okay we also need the status code because we want to return the respective status code back to our Postman yeah all right and of course the response error yep okay and now we need to actually create the implementation for our new Pisa error yeah so let's do that right so that would be okay Implement response error for pizza error yeah because uh in order for this eror this new inam to work with actic swep yeah yeah we need to do this yeah all right so there are two methods here that we need to Define so one is error response yeah so you can see the helper text right it says by default the generat response right uses uh 500 internal server error status code yeah okay but we can change that all right okay so we can say HTT response right build all right so self. status code all right uh let's do uh do insert haer yeah so that's the haer for our response yeah so let's do content type so this is why we have the content type at the top okay so we want the content type in the response to be of Json yeah okay which is why we will need to modify our end points after this yeah okay body self dot to string all right okay we also need to okay you might guess it okay modifyed our status code function here as well yeah since we're using it yeah over here yeah we're using it here yeah all right so here we just do a simple pattern matching so we'll say match self yeah so we want to return okay so if we look at the signature of this function here it returns a status code right so the status code here is simply things like error 400 44 for not found 401 for authorization issues or 500 for internal server error and etc etc yeah so for example for pizza error uh let's say no P found right right we want to return say not found so we say status code not found right so this will return uh an error 44 to either Postman or the front end yeah right so we can do also do the same thing for our Piza creation failure so for this I'll go with I mean let's go with the internal server error which is error 500 and lastly for no such Pizza [Music] found right we will go with not found right so that is once again 400 yeah so not found all right okay and save that yeah so basically this allows right actic web to return error 404 yeah when we cannot find any pizzas or error 500 yeah internal server 500 yeah when the creation of a new pizza fails yeah for example all right now let's go back to our main. RS because we need to make some changes to our end points yeah in order to leverage on the new error inam that we have just created all right so for status we're going to change and modify this endpoint yeah to now either return the Json yeah of all the pizzas in our seral DB or return uh no pizzas found error yeah so to facilitate that okay we're going to leverage on Ras uh result inam yeah which either returns an okay or an error which is which are its two variants yeah so it is a very helpful inum all right so first thing first we need to change our signature of our function here okay so so obviously instead of uh returning this default responder we're going to change it to okay results okay what we just mentioned so it will either either return okay okay or error right if you read the helper text here okay so for okay we want need to return Json which is what we mentioned just now all right okay and adjon of a vector of pzas yeah all right okay and if there was an error okay we wanted to return a Piza error right so this new Piza error that we just created here all right so that's it for the new return signature yeah okay so this line is still the same okay we are still getting all the pizzas from the Ser DB okay but now instead of returning uh HTTP response okay yeah uh let's remove these two lines since okay we're going to change how the award is being return return from this pattern matching right so if okay we do a pattern matching here and if we have results yeah found some pzas yeah okay we'll say hey it's okay we have the results and okay will wrap our Json in the okay right and we'll just pass in the found pzas yeah okay if there was nothing found yeah okay we say pizza error no peas found yeah and basically that's it right save that and let's go back to our Postman all right so back here in our Postman as you can see okay previously okay when we hit this endpoint the Slash the get/ pasas okay we have two new pizzas okay but they are not in the Json format yeah they're also not in a vector format as well right so if we click on send now all right so we found an error okay let's go back to Helix yeah so okay okay we have an error here we didn't finish our sentence with a semicolon right all right that should fix our error let's go back to postman right let's try this again so if we hit SL pizzas again yeah so now notice that we have gotten a very nicely formatted Json yeah of a vector of pizzas yeah so one pizza here with it Ser ID and pizza name and the second pizza once again with it Ser ID and pizza name yeah and if we randomly add a new pizza uh let's and say a mushroom pineapple pizza yeah I know some of you might get angry from this but this is just for demonstration purposes yeah right so if we add a new pizza here all right and if we go back to the get/ pizza endpoint okay now we will get three results yeah okay as you can see from here yeah the newly added Pizza is here all right so we will also update the post SL update pza endpoint yeah so that it will now either return Json yeah if the creation was successful or a pizza error if there was an error in creating the new pizza right so let's go back to our Helix all right so we're back in Helix now okay so let's go back to our main. RS here all right let me just enlarge so that you can see this better yeah maybe even more all right so we will need to modify the by Pizza function here all right so same thing okay we are not going to change much of the signature of the function okay but just what it returns yeah so once again instead of the default responder let's change that to result inam yeah once again it's either a Json or pza right just one pizza since we are creating a new pizza one yeah okay or an error right pza eror yeah okay and okay let's go down okay in our pattern matching over here right so instead of returning this HTTP response yeah okay we're just going to return our uh let's remove that okay we're going to return the Json wrap around in okay yeah so this is created so okay if there was an error okay we return an error here so instead of saying error buying Pisa okay we'll say error Piza error Pisa creation failure yeah so that's one of the errors that we created yeah so save that all right so it says that there's an error here okay and the reason for that is because okay for this outer pattern matching yeah yeah okay we also need to return an error right so over here okay you can see that we are returning both either the Json of the Piza here and here the error okay but over here okay if the validation failed okay we need to return an error as well yeah so let's change that okay so let's remove this default HTTP response and we'll say Visa error right internal server error so let's use this yeah right let's save that okay and the error is gone yeah all right now let's go back to post band and see and test the new knee updated post slby pza endpoint here all right so let's go back to our Postman yeah post band over here uh let's create a new pizza let's call this Sushi chicken pizza yeah so this is just something random yeah right let's click Send right so now okay if we drag this up right just above me right you'll see that now okay the result of this new pizza creation returns a Json okay of the pizza with his new US ID and the pizza name that we just pass in all right so we will also want to allow users to update existing pizzas yeah so let's go back to Helix yeah so we want to allow users to achieve that okay via the patch endpoint okay/ update Piza and using an assisting pizza's us ID all right so let's start by going back to our database. RS now over here so you notice that here we only have two functions uh with the exception of the init function so one for get all pzas and one for at pza yeah so we'll need a new function here all right so let's do that now okay so let's call this uh let's call this update uncore Piza all right so once again it's going to be async function update pza yeah okay once again we need our database stru okay and we need obviously we need The UU ID right of the assisting pizza so that we know which pizza to update yeah okay and of course the return type will be an option of Pizza yeah our pizza struck right so we'll say let find [Music] pizza all right uh equals to self right client so this is once again using the serial DB client all right do select okay and okay we want to find from the Piza model okay okay and we're going to just use a reference to our U ID here okay do await yeah so this is getting somewhat long uh so I'm going to just do this yeah so it's easier to read right and for this case we need to explicitly specify the return return type yeah so there will be an result inam okay of an option of pizza yeah or an error all right because you could have an error yeah all right and we'll do some simple patter matching here right so we say match findor pza yeah and if it's found yeah quite straightforward if it's found all right here we'll do a match yeah of what we found yeah and and if there's something in it because it's possible that okay so if we found the pizza right let me just add a command here found the pizza okay we straight away update the pizza yeah so we'll say let updated Pizza okay once again we need to explicitly okay mention the return result here yeah so once again you be the same okay it could be an error as well self uh let's do it on the next line so self do client once again we're using the serial DB client here update yeah since we are using this function to update the Pisa yeah and okay we want to update the pza with this ual ID yeah so we're using reference to that and this finalize that using this pizza as the data to update the existing Pizza Wave yeah so U ID will be the same but for pizza name okay so what we want to do here is just do a simple change of the name to say so all right so we'll say string from so yeah as simple as that and and of course we need to await this yeah all right okay and once again let's do a simple pattern matching here again match okay and if there was no errors in updating this pizza we'll just return okay the updated pizza if not okay we'll return none yeah all right pretty straightforward yeah okay over here we want to make sure that we also complete the pattern meing here so there could be nothing here as well yeah same thing and if there was an error in finding the pza so there will be here okay the other possibility that's not okay okay we'll say error yeah none right so we'll save this okay and we'll see that okay we have an error here because okay we need to do an underscore here yep all right so this is just a warning here so it's telling us that hey you have this here but you're not using it all right so uh for now we're not using it so we're going to put an underscore in front of it yeah all right so that is our update uncore Visa function okay let's go back to our main. RS right main. RS and we'll use that newly created update uncore Piza function in this new in this patch endpoint yeah okay so we have to modify this signature of this function here yeah so because now we need the database the seral DB yeah so okay we also need to pass in our DB database here all right and of course instead of returning the default responder okay once again we need to return the result inam okay of either Json of Piza okay of the updated Piza or Piza error yeah all right okay so here okay we have gotten the U ID from the URL yeah okay we just now need to call the function okay update _ pza db. update pza yeah so that's the new function that we just created yeah right so enter okay and we just need to pass in our DB and the UR ID and of course we need to await this yeah and and instead of returning the HTTP response here let's remove that yeah and we'll do a simple pattern matching here okay to check what is in update underscore result yeah so if the updating was successful we should get an updated Pizza back yeah and we'll just once again wrap it around in okay off a Json of the updated pza okay if not okay we'll just return an error off Pizza error uh we'll say no such Pizza found okay so save this all right since that we have an error here let's take a look okay so the reason for this is because okay we are using db. update pza here yeah and if we go to his definition over here you can see that it's okay the first argument is the reference to itself yeah so we don't actually need to pass in DB here so let's remove that okay yep so save and the aror should go away yeah all right now let's go back to post SP and test this newly updated patch end point all right so let's go to postman all right so now if we go to this Pat end point here okay so I'm not going to make any changes here but okay okay we're going to pass in 1 2 3 4 as the U ID uh of course this pizza or rather there are no pizzas with this U ID okay so we should get an error right so you'll see now okay above my head yeah okay it says no such Pizza found yeah so this is to show that our new created pizza errors is working all right okay so in order to get and existing Pizza okay we're going to use this get endpoint here uh and just get one of the pizzas that we have in our seral DB okay let me just change or rather let's use this yeah so we're going to sell this pizza okay and we're going to change its name to so all right so let's copy the U ID here and paste it here all right so now instead of getting no such Pizza found okay if you click Send okay notice now okay it returns adjon of the updated Pizza okay but with the updated Pizza name of sot all right and if if we go back to the G end point here which returns all of the pzas in our seral DB if we take a look at it again okay you notice now okay one of them is now sold all right so obviously this is just a demonstration of how to update something in Serb with actic SW all right so you can see how easy it is to set up and use Russ as a back end okay using actic SP with seral DB as your data base yeah and you can obviously add more end points yeah uh such as put or delete methods yeah for other features in your back end yeah okay so hopefully you have enjoyed this short tutorial on how to use rust as a backend with actic web and seral DB okay but but okay there's just one more thing we can do to make this rust backend with serial DB powered by actic SW even more awesome all right so let's dive back into database. RS in our Helix yeah so if we take a look at database. RS yeah okay so you notice that with just one model Pizza okay and three end points okay it is already around uh what about 79 lines yeah so what happens if you need to add more logic yeah more functionality uh that is related to pizzas or what if this backend uh decides to sell Burgers yeah as a new model yeah so what would happen then yeah I'm sure you can see where this is going because hey we will get so many new functions in our database implementation here and this will become a hard to maintain mass in the long run all right so in order to resolve and prevent that from happening okay we are going to leverage on something known as trades in Rust yeah so if you are new to traits in Russ okay you can think of them as a way to give types in Russ additional behaviors yeah so they are somewhat similar to interfaces in other languages where you can define a trade first and create the implementation of that trade for a type yeah okay so that is a good way for us to separate out the various functions yeah into its own data trait yeah because this is related to database yeah to keep them to keep the whole code base more maintainable in the long run as well all right so let's not talk too much about this and let's dive in yeah to create our data traits for Pisa all right for STS let's create a new data trade rather a new pcore datat trade. file yeah so this will be once again under the DB folder okay and we'll call this file pcore dataor trade. RS yeah so if you take a look all the way at the left bottom corner okay we will be creating this yeah so this will be a data trade for pza file yeah all right so we have to use obviously the pizza stru yeah right so let's import our pizza all right okay obviously we need to use our DB as well okay all right and of course we need our aex web okay and because this involves asynchronous operations with Ser DB okay we will need the asynchronous trade okay which is one of the packages that we installed or rather one of the crates yeah so that's my bad habit okay one of the crates that we installed at the start of this video okay which is the Asing trait crate okay and that's what we're going to use here so we're going to say use asyncore tra asore trade all right and lastly if there's an error okay we say seral DB error all right okay so here we'll declare our first trade okay uh which is going to leverage on our Asing trade okay and this trade will be the same name so this will be Piza data trade okay and this is just to Define to First Define our functions yeah if you recall okay we have three end points want to retrieve all pizzas want to buy a pizza yeah the post end point and lastly want to update an existing endpoint sorry and assisting Pizza yeah so update uncore pizza so we need them okay so first is get all pasas okay uh we're going to pass in the DB here all right because now we're using the functions here in this straa and not in the database struct itself yeah so we need to pass in the database later okay once we get to modifying the function yeah so next will be our addore Pisa same thing right we need our database all right okay uh we also need the new pizza okay let's not forget about that all right uh this will return a pizza all right and lastly to update an existing Pizza okay once again obviously we need the database okay and we need the U ID of the P that we want to update yeah okay all right so save that okay and now we need to create the actual implementation of this Piza data trade for our database struct yeah all right so same thing here is singor trade and here we'll say Implement okay we want to tell Russ hey let's Implement and give the pza data tra to our database stru right so this will okay later you'll see but this will allow us to use the database struck with the three functions here okay as though as these three functions are part of the database stru so the functions are mostly the same okay so we'll just copy and paste them from our database stru so let's go to database here here okay so get all pizzas add pizza and update uncore pizza right so let's do it one by one okay first we have get all pizzas right so I'm going to copy them okay copy this first and let's paste this here yep all right okay we need some proper formatting okay yep okay we just need to modify the signature of the function a little bit because now okay this is not in the database struct itself right so we cannot use a reference to self okay we just have to use the database the reference to the DAT database that is passed in all right okay so that's for get all pasas save that okay next we need to copy over the atore Piza function all right all right so copy that same thing here paste it here uh make sure we have proper indentation and of course let remove the reference to self once again yeah because we are not in a database stru yeah uh save that okay and lastly we need our update uncore pza function same thing here I'm going to copy this whole function yeah all right and let's copy that and let's paste it here in our Piza data trait yeah all right okay same thing we need proper indentation yeah all right okay and let's make sure to close this properly all right okay and of course we need to remove the reference to self and change it to the same as what we have over here uh I'm just going to copy this over here all right okay okay and let's remove the additional comma save that okay now okay we have created this new pizza data trade okay but okay we still have the three functions in our database. RS so let's remove them yeah since they're no longer needed over there let's remove them yeah okay so remove this and remove this yeah okay so now that we have done this okay okay we get an error in main. RS okay let's save this and let's go back to main. RS now you'll see hey okay we're getting some errors here yeah because okay the three functions yeah they are not directly in our database struct anymore yeah they're in the new data the new pizza data trat yeah okay but our Ras program is still not aware of our Piza data trait yet okay so in order to resolve that let's go to db. RS okay and tell R hey we have a new module and it's called pcore Data trade you see K Russ knows that it is there and is prompting us to autoc completed basically yeah so save that all right okay now let's go back to main. RS okay and we need to import that Pisa data tra here right in order to use the three functions that have been relocated in the Pisa data trade all right okay so let's see uh I guess we can put that over here so we say use create DB okay and we'll say Pizza data tra okay okay you can see that it is already prompting us okay the auto complete is working yeah and database right and that's why we can remove this and let's finish up with the semicolon save that okay obviously we still have the errors here uh which is why next we'll have to change the Tre or modify the tree functions right the three end points all right so let's start with our Gore pza end point all right so if we take a look at the error here so you can see that Russ is already telling us what to do yeah so this is why uh the RAS compiler errors yeah are very very helpful yeah so instead of doing db. get uncore allore pizzas okay r already tells us that hey you should use database instead yeah database get underscore all pzas yeah is that simple yeah okay of course we need the dot await yeah so let's do that all right save that okay and okay notice that it still gives us an error because we need to pass in the the DB yeah or the reference to our DB right save that okay and the error goes away right so we also need to do the same modification right for our post endpoint at/ by pza over here okay and same for our update end point here all right so here once again instead of using DB okay let me remove that okay we to database update pza sorry add Piza yeah all right okay and let's save that okay and we also need to pass in our DB right the reference to DB all right so save that okay and notice that the error is gone right let me just change the formatting a little bit oh well this it's rather long though okay and lastly for our update pza end point same thing here okay instead of using this uh let me just remove this okay we'll do database update uncore pza yeah okay and once again we need to pass in the reference to DB yeah so save that okay and the error goes away as well so let's go back to postman and test out our three end points again right so over here we're back at Postman and let's test out our get/ P end point okay seems that we have an error let's take a look okay let's maybe check out our data tra oh yes we need to update this as well yeah so instead of using our previous version which is self when we were still in a database struck so we need to access the client from the DB that was passed in yeah so if I save this now all right that error goes away and we also need to remove the pp here yeah because there's no need to do that yeah okay and same thing here let's remove all the self just change it to DB all right save that that all right and we also need to make sure that we don't have the same errors at the top for add uncore Pizza okay so once again this is DB right and same for our get uncore allore pzas right so this is DB so save that and all the errors should go away yeah so this is why many rations yeah regard the error messages from Russ as extremely helpful all right so let's go back to post spin once again and test this out once again right so you can see that now the end point works again yeah it's returning all of the existing pizzas in our seral DB all right uh let's test the post end point as well uh maybe I'll say BLT Pizza yeah or maybe code Cut Pro pizza right send all right you can see that the pizza has been created and if we check all the pizzas again yeah it is here in the list of visas yeah and now if we want to sell it using the patch [Music] endpoint okay it should have its name change to so yeah so let's check that here in our list of [Music] pizzas yep the name is sold all right so separating all the database related functions into their own tra or I would like to call them data tra files or files yeah uh categorized by the context for so for example pizzas anything related to pizzas can be Pizza data trade or anything related to Burgers if you want to start selling burgers can be Burger data Trace yeah it helps a lot yeah with maintaining your code in the long run yeah and hopefully this rather long tutorial on how to build your Ras backend with actic SWAT and serial DB has been helpful and if you found it helpful be sure to hit that subscribe button like and share this video with your friends and as always stay awesome and stay safe TR man
Info
Channel: WhiteSponge
Views: 20,720
Rating: undefined out of 5
Keywords: Technology, Coding, Development, Programming, React, React Native, Software, A.I, Machine Learning, Coding Tips, Programming Tips, Programming Tricks, Design Tricks, Visual Studio Code Tips, NextJS 13, Next.JS 13, NextJS Guide, Rust Crash Course, Rust 2023, Rust Guide, Rust Tutorials, Rust for beginners, Rust Programming, Rust Tutorial Language, Rust Language, Rust Code, Rust Stream, Rust Backend, Rust Backend Development, Rust for Web Backend, Surrealdb, Rust Actix Web
Id: Rnw-x21kGaA
Channel Id: undefined
Length: 108min 2sec (6482 seconds)
Published: Sun Oct 29 2023
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.