MirageJS - Easily make a mock API for React

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello class in this video we're going to be learning about mirage and what mirage is is a library that allows you to quickly spin up a fake api and work with it on the front end and this could be useful in many scenarios one of which is let's say you're working as a dev team and you're the front-end developer and the back-end developers haven't yet finished the api you can just use this tool and mock up an api that resembles your application api and has the same data structure and then once the back-end team is done with the api you can actually just plug and play your front-end app and you don't have to wait for the api to be done you can also use it yourself even if you're making the project both front and back and if you wanted to start from the front end you can actually use this to say finish for example your react app before going and doing the actual api mirage has a lot of quick tools that facilitate this and is really easy to use actually so it can save you a lot of time on uh when prototyping your app okay so go to miragejs.com and i'm actually not gonna start this tutorial i think they have a great tutorial but in my opinion it's got a lot of markup and if you're a beginner actually even if you're not a beginner it can be really confusing to use their tutorial because it involves you reading through a lot of markup and a lot of in my opinion unnecessary clutter so let's just click on the read the docs and let's get started so if we go to installation it's just going to tell us to install this mirage.js package but before we do that let's actually create our react app using create react app so let's say so i'm here on my desktop i'm going to say mpx create dash react app and let's call it mirage tut and let's use the template so let's say template and let's use the clean cra template so it removes all the unnecessary files and let's let it install and while it installs make sure to like this video and subscribe if you haven't done so thanks all right our app has been created so let's say code mirage tut so we can open this in vs code okay let's open the terminal here and say npm install mirage to js and do dash uppercase d to save it as a dev dependency and actually i want to install bootstrap as well to give it some styles and make it look presentable without having to write any css because that's not the point of this tutorial so go to getbootstrap.com and copy this npm install bootstrap at next command and let's go back let's paste that and let that install and let's head back to the mirage docs and let's look at how we can use mirage so let's go to overview so here it shows us how we can create a server which is this uh fake server that provides us with our data and here they have this cool example with movies so let's copy all of this so copy all of that and let's go in the source directory actually close these extra menus so let's go to the source directory create a new file call it server.js paste everything we copied here let me make this code bigger so here we have this create server call and then here we have this routes function and we have this namespace which what it will does it will just append this api to the start of our routes because we're pretending that this is an api and let's say if your backend had for example dash or slash v1 you can do this and it depends on your backend so you can make it resemble the exact same path as your actual api so when that's done you don't need to change anything and we have this get slash movies which does exactly that it returns us these movies just like a get request on a rest resource endpoint and the way we can use this we can save this and then go to index.js and we can simply say import from the same directory slash server and this alone will actually make it work so we can go now to app.js and here i'm going to change this up class to container so that we can constrain the width of our page and here instead of hello world let's create another div with a class of row and with the class of justify content center to center stuff in the middle and here i'll put a column so dot call and to show the movies that we just created we have to fetch them first so i'm gonna import use effect and use state from react and here at the top of the app component let's do a use effect call and inside of here let's do our callback function and here we'll use fetch so let's say fetch and mirage hosts this fake api on the same dev server that's serving the react app so we can simply say slash api slash movies oops movies and that will get us our movies and here we'll say then we get a response and because this is fetch we need to return response.json and do another then and here we'll get our json data so here let's say json and we need to set it to a state in the in this component so here let's uh do use state use the use date snippet and here let's call this movies and it starts as null so here where we get our json we can simply say set movies json and this returns it if you see in the uh in the server inside of a movie's key in the response or property so here we'll say set movies to json.movies oops move these and of course let's do a dot catch in case there's an error and we console console.log that error to the console and now let's check this out without doing anything let's uh let's save this and in the terminal let's say npm start to start this react app all right we get a blank page let's open the dev tools go to console and okay it's requesting it again and again because i forgot to add an empty uh dependency array for the use effect call so add this as the second parameter to use effect and let's refresh we get this warning um there are multiple okay this usually happens when you import the same package in two different places with different casing but i haven't done that so i'm just going to ignore this for now so there we go we get this log here that says mirage get slash api slash movies and we get status code 200 so that was successful and we get this nice console log where we can expand the response and there we go we get movies inside this response object and it has the exact movies that we had cool so that api request actually was successful so now we just need to show them on our page so let's go back to our app and here inside this column let's uh let's add a header one that says movies and actually let's give it some style i'm gonna say just give it some font weight normal to not be too bold so fw normal and here let's say text text center to center it and then give it some margin on the top and bottom my3 and here we'll just say movies and after this i'm just going to use a good old table to show our movies so here i'm going to wrap this with an expression let's say movies question mark dot length to check and we do the question mark because it's the optional axis thingy because it might not it might still be null so we'll say if movies.length is bigger than 0 let's do a ternary then we return the table that has the movies and then else we return something else i'll do the else first and here we'll return and i will say no movies and here we'll do a table with a class of table here let's do our table head so t head and we'll have the row for the head and then here we'll have three headings and oops i was meant to do three so here the first one will be the id the second will be the name i was supposed to do tab but whatever and the third one will be the year of the movie and let's do our body here so we'll do t body and let's loop through our movies so we'll do movies dot map we can straight away from each movie destructure the uh the fields so here we'll do curly braces id name and yeah and let's do the arrow and then do a parenthesis to return a table row so here let's do our table row and give it a key because this is react let's say id here and here we'll have our tds for the data so the first one actually let's do three so the first one will be the id so do id and curly braces and we'll have the name and we'll have the year all right let's save this and return there we go we get the table but it's not styled because i actually forgot to include bootstrap so let's go to the index.js so let's import both the css and the js so let's say import and do bootstrap slash dist slash css slash bootstrap dot min dot css and duplicate that and replace this with this slash js slash bootstrap.org without.js just bootstrap and refresh okay it's uh complaining that we don't have popper js installed because bootstrap requires that so let's copy that and go back to our terminal open a new one and say npm install at popperjscore and let that install all right there we go so we get our movies inception to stella and dunkirk i guess the guy that wrote the docs is a big fan of christopher nolan because i think all these three were directed by him but yeah all right so now our get the request is working let's see how we can add a post request that we can create a new movie here so let's go back to the docs and scroll down as you can see it's this easy we can just add this function this post endpoint so copy that and let's go back to our server.js so here in server.js we can just paste this so we have the post movies and then we pass the request body and then we create a random id and then we return this movie but the thing is here it's not actually adding it to these movies even though it's actually just a fake api what we can do for now because there's a better method later for now we can just copy this object and then just remove that uh colon and put that in a variable here so say const or actually let because that's more appropriate let movies equals and paste that and this should be still fine it's gonna return this movies that's fine and here where we have these attributes which represents this new movie we can add it to the movies array so here we can say movies dot push and push these attributes and then we can return the same response that's fine and for us to be able to interact with it we have to add a form in our markup so here under the header one let's add a div with a class of my4 to have some space between the heading and the table and here let's put a form without an action with an on submit on submit let's call this submit form and create it later and inside the form gonna have two fields actually first let's put a row let's have three columns so dot col times 3 and tap that so here this first one will be an input with a class of form control that's uh to give it the bootstrap styling and here this will have a placeholder and we'll say name so this is for the name of the movie and actually let's create the state variables first and then continue so here let's do another use date uh snippet call and this will be name oops name so we'll start as an empty string and here let's say use state again and this will be the year so yeah we'll start as an empty string as well and here in this input the value will be name and we'll have an onchange and the onchange will take an event and then it will set the name to event.target.value close that let's actually duplicate this entire thing and then drag it here onto this actually inside the second column and this will be we'll have a placeholder here and this will be of type number and this will be the value will be year and the uh on change we'll set year instead of set name and in the third column we're going to have the submit button so let's do a button of type submit with a class actually can i do this btn yeah actually i could so btn.btn success to give it the green color and then inside the button we'll say create all right save this and let's create this submit form function so here have it as an async function so submit form and it will take the event and inside actually before they try catch block let's say event dot prevent default so it doesn't really load the page and here inside the try block we'll actually send our request so let's say construct equals await fetch and we'll send a request to the same endpoint slash api slash movies and because this is a post request we have to add some options here so do an object here's the second parameter for fetch and say method is post and also let's add a body of the request and this will be it's actually saved to have some formatting okay it doesn't format it properly but let's say json.stringify and we'll send the name and the year as the object so name and yeah so we have to close that and close the object i think there's an extra pair of curly braces yeah cool and if that's successful we get the json from it so we'll say cons json equals await res dot json and now we just need to add it to our list so we'll say set movies do an array spread the existing movies and then do comma and add this new movie so this will be inside of json.movie and also let's reset the field so we'll set name to empty string and also set year to empty string so that those inputs are emptied all right let's save and this give this a test so let's go back to our app so do i have to refresh yeah okay just refresh all right this is not taking the full width so maybe uh let's go here to our columns where we have the input add the dash five so they take more than a third and then for this one just add dash two save that looks better open the dev tools just to check and here let's add say let's add for example mad max so mad max the new one fury road okay i can't type road and the yeah i think it was 2015. all right let's click create and there we go it's actually added to the list and we get this post request 201 which stands for created so that was successful and our inputs were emptied nice now of course the idea that the app you're working on will not have a simple ui like this it will be like your fully fledged app but the idea is that it facilitates interacting with the api even though it doesn't exist because this is just a fake one all right let's add the rest of the routes so we have the full crowd functionality and actually okay here there's another feature that mirage has which is pretty cool which is models so we can have these models just like we have in our data layer on the server when using an orm we can have data models here so we can turn this movie into a model and have some extra features that you'll see so let's go back to our app and inside of server let's copy or let's import another thing called model from mirage.js and here at the top of our server we can say models and then open an object and then we can say movie for our movie model and then give it type model and then do a comma here and we also have something called seeds which if you're not familiar with is a way of adding fake data when experimenting with your app so here so we have the seeds function that we can call which takes the server and then creates fake data like here these movies so we can actually just copy this because it has the same data that we copied earlier so let's go back to our app so inside of our server paste this seeds so we're doing the exact same creating these movies but instead now they will be in this movie model and we can have some more features to work with than just a plain javascript array so we can actually remove this and now we can use this schema object and then access our models using that so now in our get route which is here this we can actually just copy this get route and then paste that there and as you can see here it's using the schema and this will work exactly the same because it's creating these but this will not work now because it's using that javascript array that doesn't exist so i believe they have all the routes written here so yeah here we can just copy these actually we can copy all of them because i'm not going to do some fancy logic or we're just going to use the base features just to be introduced to it so let's copy all of these paste them here instead of these two and now this post request as you can see now it's using the schema movies and then creating this new movie and by returning it it actually returns this newly created movie now let's save and make sure that everything works the same refresh and as you refresh your data is reset to that see this data so you don't have to worry about it if you delete it you're not going to have to manually create it again let's test create in a gun so let's go with mad max again 2015 create there we go so that was created and it's automatically giving them these incremental ids just like you can have like when using sql all right let's uh consume the other routes so we can start with deleting let me make this a bit smaller so we can add a delete button here in the table in front of every movie so let's go back to our objects and here in our table we can add another table heading and we can say call it actions because we'll have the edit later as well and here add another table draw and here instead of here we're going to put a delete button so say button dot btn and because this is delete we're going to say btn danger to give it the color red and this will say delete when this is clicked so we'll say on click we'll call a function so do a callback and this will call delete movie and we need to pass it the id of the movie so it knows which movie to delete so let's scroll back up and create this delete movie function so here let's do it as an async function so const delete movie takes an id we'll say await fetch from the same endpoint actually not the same let's do backticks slash api slash movies slash and then do dollar sign curly braces to concatenate the id and add some options and say method is delete and after this once that's successful we need to remove it so we'll say set movies so we'll remove it from the local state uh set it to movies dot filter and filter movie where movie dot id does not equal this id that was given so it keeps all of them except that one now let's save that and go back to our app so now when we click on delete boom so that was deleted and we get 204 so successful but no content so that was deleted i don't know why i clicked on response there's no content in the response data and it was removed because we removed it from our local state and if we can delete we can delete all of them until we have no movies cool i'm going to refresh because i like to have some movies all right let's add the update and to keep it simple i'm going to have a update button here and every time we click on one of them it's gonna fill the fields here with that uh movie data and then turns this form into an update form instead of a creation form so let's go back and scroll down where we have our delete button inside the table before that actually let's duplicate this and this will be btn warning to be yellow and this one clicked will say set movie to update that id and then change this to update and what we can do is um we can store an id of the movie that is being updated so here we can do use state again and then say movie id and have it be null and then do another variable that tells our component that we are in update mode so we'll say use state and here we'll call it updating and this will be false initially because we're not updating initially i made a typo here so updating all right let's create this set movie to update function so here this will be a regular function so set movie to update and this takes the id and then we'll say const const movie equals movies dot find and we'll find the movie where the movie dot id equals this given id and then we'll set updating to true and we'll set movie id to this id or actually to the movie dot id and here we'll say if no movie somehow that movie doesn't exist anymore we just return and do nothing and under here we'll say set name and we'll set it to this movie dot name and also the same for set uh year to movie dot yeah and let's change that create button to yes so here where it says create we can do an expression and we'll say if updating so do a ternary and then we'll say update and if we're not updating then we'll say create so let's look at our up all right so let's put some margin between them so where is it actually no it's down so here yeah btn warning let's add some margin on the right so mr3 and let's go back okay i forgot this bootstrap and now it's changed to me so margin east three cool so now if we click on update here there we go so this changes to update and the movie details are set in these fields for us to update it now let's make it so that when we click update it actually sends a patch request and updates that movie okay so let's go where the form is being submitted so submit form here so now this is for creating a movie so we can actually just cut all of this and create a separate function here call it create movie and paste all of that here and then here we'll say if updating then update movie which we haven't created yet else it's create movie which is this one right here so let's uh we can just duplicate this actually so duplicate the create movie and rename this to cree uh update movie rather so it would be very similar we send a request to the same endpoint but here the method will be patch actually so it's not the same endpoint because this is an update so change these with backticks and then do slash dollar sign curly brace and give movie id because that's the current movie that's being edited and the body is the same here we get the response that's the same the only difference is that we don't actually add the movie because it's not the newly created movie we just update uh we just find that movie and edit it so remove this and then here we'll say we'll find the index of that movie so we'll say const index equals movies dot find index of movie where movie dot movie dot id equals the movie id that we have and don't be confused this is the index in the array and not the id of the movie because we already have that and now that we have that index we'll say actually we need to make a copy and then and then update the movies because we need to do that for it to be reactive so here we'll say const movies copy equals and then spread the existing movies movies and here we'll simply say movies copy index equals json.movie and now we set movies to movies copy movies copy like that and we reset the fields and we also set updating again to false and also set the movie id so set movie id to null again all right let's save and check if this is working properly okay let's refresh just in case let's say we want to update dunkirk and just change the year to 2015 and click update all right there we go so now it's 2015 and we got this patch request that was successful 200 and we got the movie back and we found it in our local state and replaced it cool let's test create and make sure that it's still working so let's create another movie let's say what movie do i like uh yeah birdman birdman and i believe that was out in 2013 hit enter to create there we go so the fields are emptied and birdman was created and we can delete everything still works exactly the same as it was cool so there are some other features as well that are cool that you can use for example there's shorthands actually all those endpoints if they're exactly the same as this you can just replace them with these shortcuts and let's go back to our server js and paste these here the only issue is that i had issues with post and patch not working because of like some serializer setting which we'll talk about later so i'm going to remove this post and patch and here remove this delete and remove the two get endpoints and then save and everything should work exactly the same so refresh all right so getting them works and actually we don't have any ui interaction to test getting a single movie but it actually works so here we have delete that works still and also update and here we add some numbers cool so everything still works even though now the syntax is way shorter so that's another nice feature if you're just using the basic routes so let's go back and let's scroll down so yeah we talked about seeds which are called factories where you generate fake data so let's see we have yeah relationships so we have model relationships just like we have in a regular orm so for example here they have cast member members of movies so let's say for every movie you wanted to store the people that worked in the movie and that model we wanted it to be related to that you can do that here so let's actually copy this and go back to our server and scroll up and paste that here i'm actually going to rename this to just actor instead of cast members so here actors so if you're familiar with nurm has many means that this movie has many of the actors and every actor belongs to one movie or not one movie belongs to a movie couldn't belong to many movies so now we can create actors and actually add them to these movies let's see do they have some examples of actors yeah so you can straight away create them inside the model itself or you can create them outside which is what i'm going to do now because i want us to be able to attach the same actor to multiple movies so copy these three server create calls and let's go back so inside the seats call here paste that and instead of just creating them on i put them in variables so do alt control or alt command and then do two arrows and here's a const actor equals let's remove those trailing commas and here instead of cast member it's just actually actor because that's the name of the model that we have let's see we have matthew mcconaughey anne hathaway and jessica i don't know who this is i'm just going to replace this okay who was in inception we had oh yeah we have leonardo dicaprio ricardo dicaprio let's see let's add two more so in dunkirk i know we have uh tom hardy and actually he's in uh inception two so we can add them to and add him to both so that would be a nice use case and we also have i think silly and murphy i'm pretty sure i'm blanking on them so cillian murphy in dunkirk let's give them names to say that they don't conflict so here let's say matt and anne and leo and tom and good old sillian who's actually like 50 or something and looks younger than me all right so save this and to add them we can simply inside of this create movie call inside of this object for example for inception we can just hear add actors and add an array and who do you have inception so leo and tom and i'll just copy this and here do comma oops comma paste this so here in interstellar we have uh matthew mcconaughey and we have anne hathaway and then with dunkirk we have tom that's fine we have tom hardy and we have cillian all right so now let's save we can't actually just fetch them because once you fetch the movie so for refresh all right tasmania is not defined okay i forgot we have to import these functions so has many and oops i copied the wrong thing so has many paste that and also belongs to save all right so now if you check the response actually still will still be the same which is a good thing because the actors is a different model and there are multiple ways of including it but here i don't want to include it i want to show you how we can fetch them separately so what i can do is i don't want to create a different page because that will involve us having to implement something like react router but instead we can use a pop-up model so let's go to the bootstrap docs so we can just grab a model so model and go to model and we can just grab this basic model so copy this entire div and let's go back to objs and actually maybe just outside of this row add it here this will be hidden we just need to trigger it so let's see how can we have a button yeah we can have a button like this to trigger it like this so copy that button and we can actually add this button as the uh second button here because we need to have one for each movie and this will say let's say actors let's replace the button to button info and let's give it an on click so on click uh let's give it a function here call it fetch actors and of course we need to pass the id to know which actors to fetch of which movie and actually i noticed now even when you refresh it says no movies briefly and then shows the movies which is not uh correct so what we can do here at the bottom where we have our ternary here well we have colon instead of just saying not movies uh or no movies we can check if movies is truthy because here we're checking the length and then if that length is not bigger than zero then we check if movies exists in the first place and if it exists and the length is not bigger than zero that means there are no movies so here we can say do a paragraph and say no movies and then here the another ternary so here if we get here that means in our app we're definitely loading so we'll do paragraph here p loading dot dot save okay fetch actors is not defined let's create that first let's scroll up and here we can do another async function say fetch actors and this takes the id of the movie and then in the try we'll say const result equals await fetch and then let's do backticks because we need to concatenate stuff so slash api slash movies slash dot sign curly brace id slash actors and actually we need to add this endpoint now that i think about it so let's go back to server and scroll down under this delete we'll say this dot get get and slash movies slash and then do colon id to have the parameter and then slash actors and our handler takes the schema and the request and then we have an arrow and here we'll say let movie equals schema dot movies dot find request dot params dot id all right let's return the movie dot actors and simple as that now we get the actors so save and here let's say cons json equals await res.json and actually we need to store these in local variables so let's scroll back up and do another use state call use state and call this actors and have this null at the beginning and let's scroll back down so after we have the json response we can simply say set actors to json.actors and actually we need to show them in the modal so let's scroll down where we have pasted our model so here modal title we can just say actors and here we have some text in the modal body but instead we'll just do curly braces and say actors and actually do the optional access thing and then say map and for each actor we're gonna return just a paragraph with uh the name of the actor so actor dot name and actually let's give it a key so the react doesn't complain so key actor dot id and let's remove the modal photo because we don't need these buttons so remove these save and okay let's give this some margin and also it's complaining because somewhere we have class because we copied stuff from bootstrap so select this class equals and do ctrl d everywhere and then add a name to it and let's give this button some margin so actually where is it yeah it's here so this btn info add another me3 and save refresh course so we get actors and if we click on inception actors our request was successful so we get a response and we get our actors but there's a problem here class list can i read class list of undefined of the model okay this button is targeting the example model id but yeah but our model doesn't have an id which is uh usually it does when i copy it from bootstrap so let's add id example model because you can rename this to anything save and let's uh now that shouldn't happen all right there we go so we get our model and it's actually fetching the actors and showing them and i made a typo here so this should be actors and let's actually add the class fade so that it kind of comes in slowly not like jarringly all right let's refresh cool so as we click on it it actually sends the request and loads the actors nice and of course it loads the actors relevant to the movie that we clicked because as you can see here we're fetching for movie one or two or three depending on the one we click nice so now we're able to use the relationship between the movie and the actor and fetch the actors that are in a specific movie there's a lot more you can do with mirage you can do a bunch of things you can use serializers which is basically the way you transform your response because there are different specifications of how api responses are are given different standards to that and you can get this json api serializer they have a couple of nice api serializers that match popular api uh standards and it has this pass-through feature which is a nice feature where let's say part of the api is complete and the other part is not complete and it's actually being served from the same port on your machine locally of course with create react app this can't be but let's say if you're using something like next.js and your api is being served from the same server that serves next that can be a problem let's say you have slash movies but you don't have slash actors in your apis so you can use slash actors with mirage and then when you use slash movies it just if it doesn't find it in mirage it actually goes to the actual api that's on your machine which is pretty nice and also has some advanced features like graphql which is nice you can have a graphql api instead of a rest api for when you're testing your ui and yeah it's a pretty cool library to use for prototyping before your backend is done alright that's it for this one please again make sure to like this video and subscribe if you haven't done so yet and i will catch you in the next one cheers
Info
Channel: Classsed
Views: 3,698
Rating: 4.9259257 out of 5
Keywords: miragejs tutorial, react miragejs, react mock api, node mock api, json api react
Id: Xw3K6Kk5Npw
Channel Id: undefined
Length: 36min 8sec (2168 seconds)
Published: Fri Apr 02 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.