JAMstack Crash Course - Build a Full Stack Application

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
maybe you've heard of the jam stack or maybe you haven't but if you're interested in learning how to build apps with the jam stack welcome to this Jam stack crash course where we will build a full stack application using some pretty cool technologies like fana DB for the database Netta Phi for hosting and for serverless functions and then react on the front end to bring it all together I hope you are as excited as I am so let's go ahead and get started all right you may or may not know what the jam stack actually is so let's talk about that before we actually get started building this application Jam stack stands for JavaScript API x' and mark-up and the interesting thing about this is that even though Jam stack seems to be the new hotness it's really nothing new we've used javascript for years we've used API is to go and get and interact with data we've used markup and HTML and then markdown and things like that we've used those things for years Java stack is really this new way of putting those things together and a couple of things that are important you can check out some information on JMC org is that you're building fast and secure sites that are delivered by pre-rendering files so you get into some of the conversations around static sites pre generating HTML one of the most important things here though is that these files get served directly from a CDN so let's say we have a reactive application and we go through the build process those files just sit on a content delivery network or a CDM and then when a user requests that web page those files get sent back directly there's no dynamic calculation of those pages it doesn't mean you can't do dynamic things on the front end it means that those pages are served statically from a CDN and you remove the requirement to manage or run web servers now the interesting thing about this is if you don't have a server then how do you add back in functionality and this is where metla Phi comes in for two things we host our site in neljä fire we can host our site identify as a CDN now if I also has in my mind the easiest way to implement serverless functions as part of your Jam stack application so what we're going to do is we're going to use fana DB which we'll talk about in a second as our database and we will interact with that database through our net low Phi serverless functions and then call those functions from react front end it's actually a lot to put together but I think it's gonna be really exciting now I do want to share a couple of resources as we get started one you'll have a link to the source code so you can go and grab all of that and then a couple of other things online James Q quick comm you can find all the courses and webinars and things that I do including I've got a free cheat sheet for natla fire service function so all the configuration and things that we do identify to facilitate all of this you can grab that cheat sheet and it'll just have kind of a walkthrough of how to set all this stuff up as well you can grab that for free I also have a reactants herbalist full stack web development course that you can check out as well links down below so this will basically be kind of a beefed-up version of what we do today adding things like authentication and all the configurations and things that you would need so all of that said what we're gonna do is actually jump over to fauna DB and let's actually go to the home page here so in fauna DB this is the data API for your client service applications fauna really prides itself as being a database that makes a lot of sense in the jam set and specifically when you're using serverless functions like we are today so that's why it makes for a great fit just for the jam stack in general so you will need to go ahead and sign up for a free account and then I am logged in from my github repo for my github profile so I can log in through github so when I'm logged in I've got a database here called Cerberus fauna and what we're gonna do is end up creating a new database that was the one that I was testing for the demo and so we're gonna create a new database and we're just gonna call this list Oh links and it says cannot contain spaces so let's just make this all lowercase and connected by hyphens instead of spaces so let's go ahead and save that and then what we're gonna do is we're actually gonna work with graph QL and this which I think is gonna be a lot of fun so if you're new to graph QL this is basically kind of an aggregated way of handling your API you're what would have been REST API requests so let's say you're trying to access some resources through an API usually make an HTTP request and in you have like a node server for example and that end point will go and get the data that you need out of the database the problem with that is that if you need different pieces of data in different scenarios you don't really have as much control over that so the power of graph QL is the consolidated space or place to request exactly what you want so as a requester you're able to only get the things that you actually need it's pretty interesting all right so what we're gonna do is we're gonna import a graph QL schema and the beauty of fana DB is we can import a really basic schema and they will take care of almost all of the actual graph QL implementation and configuration behind the scenes that we don't have to worry about if you've ever worked with graph QL directly yourself you probably realize or will understand how much this is taken care of for you but what I'm gonna do is I'm going to show you this is gonna be our database this is the definition this gql file a links gql file this is gonna be what our application is so what we're gonna do is take this file where it defines a link object and it has a URL a name a description and whether or not it's archived boolean and then we have a query type and we're saying that you can query for all links but really graph QL is gonna take care of the rest of the stuff for us so let's go you'll need to make a copy of this file it's in the source code under utils inside of functions actually let me just show you that inside of the source code under functions and then utils you should see your links gql so you want to download that file or create a copy of that yourself and then we're gonna upload that to fajn a DB so let's go in and say import schema and I've got this locally under my machine all right so I'm gonna go and grab that links gql file I'm going to select to import that and you'll see fun and DB actually maybe doesn't even take any time has done all the behind-the-scenes stuff for us so the interesting thing about this is inside of now this graph QL tab we can write a query so a graph QL query in this case we'll start with query and then we can do if you ever need help in here option and space will give you some tell us on what you can do so inside of here for queries we can find a link by an ID or just grab all the links and so for each link what we get back is a data property that's just kind of a graph QL standard there and then for each piece of data that we get back for each record out of the links object what do we want to query what information do we want we probably want all of them here but we could select if we only wanted the name or we only wanted the URL or we only wanted the description or what was the last piece in here if we want an ID and then if we wanted archive now obviously I've added all of the information here you may not want all the information so this is the power of graph QL of really being able to specify exactly what data I want to get back now I can run this query this is a really cool graph you will explore it here and you see what comes back is you have a data property that's just kind of what graph QL returns back and then you have all links so this is matching the query name and then you have data which then matches this thing and then if we had any records we would see those populate here so what we're gonna do is let's also let's open up a new tab and now let's do a mutation so inside of our mutation what can we do well we can create update and delete links and these are the things that are taken care of for us in fauna DB which i think is really really amazing so let's just kind of simulate here creating a link and with our create link we'll need to pass what information we want to use to create it so it's kind of like a function that we're calling and we passing it what information it needs so it's going to need a data property and that data is going to include the information for the the link itself so let's start with our name property and we'll just call this test link and then we'll have the URL property and this will be HTTP slash /ww james q quick comm and let's go ahead and give this a name of James website all right so there's the URL then we'll have the scription and this is James's site I think that's all right we do that okay all right and I wouldn't need an apostrophe but that's okay so we've got the name the URL the description and whether or not it's archived so in this case we'll say archived is false and that will be probably a default thing that we do if you archive or if you create something it's probably not archived by default and one of the things I forgot to mention is inside of a graph QL we're defining these three properties since we're using the exclamation these are now required archived is not required all right so we could just not pass archived if we wanted to but we go ahead and specify this thing to be false to start and then inside of our create link after we create it what do we want to get back well now we can just get kind of the information about that object so we could get let's say the name and the underscore ID property the underscore ID is one that fana creates for us so let's go ahead and run this and what this should do is create that link if we've then come back to our query and query all links again now we should see our new link was added so we'll get into doing updates and deletes in here as well but this is the basics of doing a graph QL query to query or send a mutation to either create recreate update or delete data all right so we've got that set up now one of the things that I want to do is I'm going to choose a directory and I'm gonna run create react app and in this case all I want to do is create a new react application that's gonna be the base of our project so I'm gonna run this and I'm gonna call mine fauna DB jam stack app whatever so this is MPX and then you're running create react app to create this new react application I'll let that run and then we'll open this thing in a second now we can go ahead and talk about a little bit more maybe about net Liffe I'm so we will use net liffe ID to host our application and then also use it to run these service functions locally so notify has a net Liffe I CLI which is really nice for being able to run your your your service functions locally and be able to test them and that's what we're gonna do and it works really nicely so you will need to go ahead and install the net Liffe IC and CLI globally on your machine so run npm install net Liffe i CLI and you'll have that for us to then run here in a second so let's see how I think I've got some I think those errors are okay that that are in there this should be wrapping up here in a second and then we'll get started all right so that finished installing and I'm going to open that up inside of vs code and then close down this one all right so if we were to run this we could do NPM run start and what we'll see is it's just a basic react application I'm assuming at this point you probably have some basic react experience otherwise a lot of this will be pretty new to you but what we really want to see is how to use Neto Fiserv Willis functions so to do this what we're going to do is create a directory called functions this is as you might expect where all of our functions will live and then I'm going to create a hello world Jas and a service function is a file that exports a handler so exports that handle or equals and then it has three properties event context and call back so this is your each individual endpoint or service function is literally just a function definition and in this case I'm marking it async and then you can return a status code or an object with a status code of 200 and then a body with a message of hello world maybe something like that so that is your first service function which is pretty nice and then we need to now run this so usually we would run Neto phi dev as the command but we need to create a configuration to tell natla phi how to run this stuff locally so this will be a net low Phi Tamil file and I'm gonna grab I'm gonna cheat and just kind of grab a copy of the this over here just to kind of show how it works and what we define this build command and then a functions property which is going to tell Nell fi where our our actual service functions live so with an elephant nullify CLI installed we can run neckla phi dev and this should start up our lambda server at three four five six seven as well as it'll actually run the front-end part which is react which is pretty nice so with our service function in place we can actually go to slash dot Neto Phi slash functions slash and in the name of that file which in that case was hello world and I think I forgot one thing inside always forget this we should stringify this object so anything you return out of here if you want to return JSON you have to actually send it back as a string in the body so save that and refresh this page and hopefully now we'll see an object comes back with hello world super cool so that is our base serverless function and what we're going to do is end up creating a service function for each one of the crud interactions inside of fauna DB one for creating updating deleting and what are getting all of the links out of our fauna DB database so let's come back into fada and one of the things we're going to need is a secret key that we can use to interact in upon them so under the security tab of your database you'll want to create a new key and then inside of here make sure you grab a server key so these are keys that we can use on a server ironic because we're working with Cerberus functions serverless doesn't mean there is no server it means we the developers don't care about the server we don't have to maintain it or do anything with it that server is just given to us so inside of this key name let's let's just call this it doesn't really matter test key doesn't really matter what you call it and click Save and you'll want to grab the secret key now I'm gonna get rid of this key by the time you watch this video so you won't be able to hack my stuff but copy this save it somewhere because after you move off of this page you'll never see this again this won't be display it so copy it now and then what we're going to do is come over to our project and we're going to add a dot env file now dot E and V files are made for environment variables that you want to pull into your application typically these are things that you want to be secret in this case the secret key for fauna so the way you create key value pairs in here is you give it the name of the key the name of the thing that you want to access the key here usually these are all uppercase and then separated by underscores that's just kind of how it is and then the last part here is the actual value of the thing so I'm going to save this I'm also going to make sure inside of my dot get ignore any time you add dot env files you want to make sure that you ignore them so that they don't get checked into your source code make sure you hear me don't check these into your source code all right so we've got our dot in V now that means that we can actually use this thing inside of our service functions so let's do let's maybe create a getter for getting all of our links out of fana DB so let's go into functions and let's do a new file let's say get links dot J s and the same thing this will be exports handler equals what async and then the only parameter I need is the event so I can actually define my function this way so to be able to interact with fauna DB what we're basically going to do is send the graph QL query in a rest request an HTTP request to fajn them to do that we're going to need to install Axios as a package it's a package for making HTTP requests easier and then to work with our environment variables we're going to use the dot env package as well this will take the properties out of this env file and let us access them inside of our application so I'm going to install both of those and then for specifically for well for both of these so one with Axios we will require Axios and then just get it that way and then for dot and V will say Kant's are actually will just say require dot e and V dot config this will grab set it up to grab all those environment properties grab them and then put them inside of our application so that we can use them oh so all right what we want to do is create an actual query to be able to send over to graph QL so I'm gonna copy this I'm gonna grab the linked queries and grab the get links query and there's no reason for me to really write all of these over and over again so this is why I'm just kind of copying and pasting them in so this is not that this is the query that we are going to use to get all of the links out of fauna DB and if you notice this looks a lot like the query that we actually wrote right inside a font of DB so you can go and experiment inside a font of DB that the query thingy there and then you can just copy that into here so we're using this get links query and then what we want to do is create an axial request where we're going to pass in this query and any variables that we need so this will look like will await we're using async await in here we'll call Axios and we need to tell it what the URL is that we're trying to request now this is one of the interesting things about font is the graph QL API endpoint is the same for everyone the difference is is the secret key that comes along with it and we use this secret key with as an a bearer token and what this means is we'll have headers will have inside of that a proper property of bearer and then I'm going to use es6 template literals because you have bearer and then the actual secret key now remember we use environment variables and we configured all this to use our environment very well so that we could do something like process env and then the key that we want to use or the variable that we want to use which in this case is fauna secret key okay so we're building up our requests with these headers this one will be I guess they all need to be a post so this is going to be a post method all right and then we also need to include the data in here so data is going to include the query that we wrote above so that thing is called the get what do we call that get links up there so we'll say query equals get links and then the variables property in this case will just be an empty object we're not doing a mutation a mutation would take data going in we're not doing that we're just making a query so what we'll do is we'll one we can surround all of this will attract a or actually I think this thing will come back with error so let's just look at I think this thing is going to come back with a data property and so let's do this let's just log out console.log that data that comes back and what I'm doing is D structuring the data property from the response that comes back so then we want to log this thing out and let's just return status code of 200 and this should be an object still sorry about this status code of 200 and then the body lets stringify the data that we're logging out there alright so hopefully what we'll see is we can get data back here so let's run at the phi dev and we'll see this run this thing is running there what we want to do is head on over to not the hello world function but the get links function and we'll see what happens actually cool that came back with data and then all links and data remember that from inside of our graph QL query where is it yeah so over here data all links data that comes back well perfect and then it has the actual information in it which is great so this is able to query all of the links out of fauna dB now a little tip here in net lapham you have to type dotnet Liffe i slash functions each time and honestly that kind of sucks and so you can simplify this a little bit I'm just gonna copy in this little snippet here so this little snippet is in the cheat sheet that I mentioned inside of this serverless functions cheat sheet you can go and grab for free and it will show you how to redirect everything from an ape slash API call to the full net Liffe i / function / splat which it kind of means whatever comes after that so I'm gonna restart natla phi dev and what we should be able to do once this is up and running is inside of here now stop opening up we can get rid of net dot net loaf I slash functions and just do slash API get links and that should do the same thing sweet this is a lot easier I recommend setting this up every time you do this so in this case we're able to query all of this stuff but really we want to simplify this a little bit because we're gonna end up doing the same sort of thing for each one of these several is function is that we have create read update and delete and so inside of functions I'm going to create a utils directory inside of there I'm gonna have a sin query J s and then I want to copy a lot of this stuff over so I'm gonna grab this whole thing here alright and I'm gonna get get it out of there so let's copy it and let's come over to send query and we're gonna say module dot exports what's we're doing what we're doing is exporting a function that can be called from each one of the endpoints that we have the serverless functions that we have and so this thing is going to take a query and variables and then inside of here we're gonna do a similar thing but we're gonna take in this query and we're gonna send the query so we'll do that little shorthand in ESX and then we will send the variables along as well now we need to import Axios again so const Axios equals or choir Axios and then we want to make sure we require our dot env and call config on it so we are exporting this thing and what I want to do is I'm going to grab the data property off of the data property if that makes sense and then also grab the errors property this way we can check to see whether or not there were any errors inside of here and this actually looks like this so this is gonna say it's gonna grab the date the response data on that thing it's gonna have a data property and an errors property which may or may not actually have errors and then inside of here what I want to do is check if errors if there are any errors I'm going to log them out and then I'm going to throw an error so throw new error something went wrong not being super specific here and in the end I'm not returning from a server this function I'm just actually returning this data so there is our send query now another thing we can do is we can create a new file of all of our queries so we can call this link queries j/s and i'm going to copy over this get links and then I'm going to say module dot exports equals a function that are not a function an object that has all of the queries that we are going to use inside of it so there's our get links query there is our send query so here's the thing that we will pass a query to as well as variables and then inside of get links we can change all of this stuff to go and grab so conce get links we want to import that thing from our dot slash utils and in link query so when you want to grab the actual query out of that and this is the totally wrong syntax that should be a require instead of the import syntax I was trying to use that was totally wrong so we want to get that thing and then we also want to get the send query function from our other utils don't I take the damn right dot slash utils there we go and send query so now that we are importing the query and the ability to send the query now we can just call this thing so we can surround it with a try-catch in case anything goes wrong we will call a wait send query and pass in the get oops the get links query remember that's just a graph QL string then we will say kotts data equals res dot all links data kind of just how you grab that information off the response and then we'll return a status code status code of 200 and then a body of json stringify data alright and I think the only thing we're missing is a catch down here and if something goes wrong we will log out that air and get rid of the brackets there and then we will return a status code of 500 and then a body of json stringify not being too specific here but just kind of giving an error message back to the user so we've now made this stuff look a little bit a little bit better because we've got cin query in its own file and we've got all of or not all of them yet the linked queries in its own file now we can reference this and the individual service function gets a lot easier one of the things that I think is useful is I'm going to create a formatted response js5 and I'm going to say that this is going to be a function that will take in a status and a body and then I'm going to return the thing that you have to do in service functions which is return the status code and actually I'll rename this to status code so we're returning the status code and then our body equals json stringify of the actual body now what I'm doing is I don't like writing this json stringify thing every time so what I'm gonna do is in each one of these I'm going to M not import but say kotts format and actually yeah I guess formatted that's fine I could come up with a better name but just a formatted response equals require and then in our yuto's formatted response and then what we'll do is we'll just return formatted response and pass in these two parameters does that work formatted response and pass in parameters instead of an object okay so that should be a little bit simpler hopefully you see and then we'll do the same thing down here formatted response 500 and then an error message something went wrong all right that's just a little preference of mine again this is in that little cheat sheet that I talked about the net LaFave serverless functions cheat sheet something I enjoy doing so hopefully after all of that restructuring and formatting what we'll see is we should basically see the same thing this should come back or slightly more formatted this should come back with all the data that we need which is really great all right so we've got all of all the ability all the organization around this to be able to query links now I want to go into linked queries and let's add a let me grab linked queries I'm gonna grab this snippet for creating a link and then we'll just copy it in and again you have access to the source code so you can go and do the same thing well let's copy in the create link and then let's export it as well and the create link is a mutation so in this case what we're gonna do is pass information to this query we're gonna pass a name property a URL property a description property and then it will call the create link mutation and it will pass in each one of these variables as the values that are needed to create that thing now if that didn't make sense inside of graph QL playground under create link we will have if you look at the example here it's we're hard coding information to pass in as the data now we're taking these in as parameters which are in the variable section of what we're working with so that is our create link query that we will also export inside of our functions let's go ahead and create our create link function and in this case I'm going to copy get links I'm gonna copy everything out of here and come back over to create links and in this case instead of get links we want the create link query then we want to send query we want to send the create link query and we also want to grab information from the body so this is information that's submitted from reactant we want to grab it here so we grab the body by saying json stringify of event dot body so it comes in as a string and instead of stringify we actually want to parse that string so it is a string we want to parse it into a body object and then from there from that body I want to grab the properties of name URL description okay so there is those the properties that we need and then we'll just say Const variables equals name URL description and we'll create an archive property of false so we'll go ahead and set that to false by default all right so there is our list of variables and we want to pass them inside here and I think the response that comes back let's double check this create link the thing that comes back is going to be a little bit different so instead of our res right here we'll actually just grab the create link property now create link property if you look over here is going to be the actual objects that comes back to us so it's called create link but I like created links I don't know this is something that I did create so created link in here I'm basically just renaming this so the create link proper I'm renaming to created link and then that's the thing that I actually want to return so we can return in here created link all right hopefully all that stuff looks good now the way we test this is we have to open up something like postman or insomnia is another one I've always used postman and I enjoy using that so we'll need to go into postman to test out these requests all right you can see I've actually been testing inside of here before do I have a post yeah I've actually gotten this up so I'm gonna send her a post request to the localhost 8 8 8 8 Netta 5 functions you can also simplify this with API because of that configuration that we created and we'll say this is the create link and then inside of the body we will have our link here let's just say HTTP colon colon james website again that's fine and we'll just say james website again description doesn't really matter what all that stuff is so we're sending a post request to our server list function create link and then we're including the information that we need the URL the name and the description so i like we'll see let's test this out let's run it and let's see what happens hopefully what comes back is an actual object although it looks like this is not coming back i wonder if we've got anything in here says 404 for create link and i think the problem here is when you add a new function inside of your functions directory now if I Deb doesn't capture that thing or know what's there necessarily so I think we just need to restart our net LaFave so let's get that a second to get up and running I don't need this tab let's try this again inside of here we see that that comes back sweet and hopefully that means that it's been created if we then go and we can just come and do this in the browser if we refresh now we should see there's multiple links here which is so wait that's pretty cool I think so we have the ability to create links now we need to finish out our crud operations with update and delete so I'm going to do a little bit of copying again for these queries just because they're kind of tedious to paste in and what I'm gonna do is actually paste in the entire file so and then we'll talk about it so I'm gonna get rid of all of this and paste it in the new stuff so the only thing that's different is we still have our get links query we had that before we still have our create link query now we've got update and delete so these should look pretty familiar with you update in this case is gonna take in all of the properties ID archive or yeah ID archives ID because it already exists and it has an ID property name URL description and in just the same way that we called create link in this case we call update link and pass in those pieces of data the ID and then the data itself same exact thing now we're just updating instead of creating delete link is actually a lot simpler to delete link all you need is the ID and then you call delete link and you can pass back the ID of the thing that you deleted really not too bad and then we export all of that stuff so now that we have all of those queries in place we can now create our two additional functions server list functions that we need one is our up update link J s and then we will also need our delete link delete link J s I'm going to cheat a little bit again I'm gonna grab everything out of the create link we go on to update link and do that I'm going to the only real thing we need to update I think is let's just replace and if you select that information and inside of es code do a find you can pull down the replace and update this to update link and let's go ahead and replace both of those so now we're getting the update link query we are sending that query so now in our body we want to get all of the different pieces of information about this link so we'll get name URL description and then all so we want the ID as well as the archived and then we'll want to update the variables to include that information so we'll put in the ID as well as our kyv is already in there so that should be everything and you might be wondering why don't I just parse this body and then send that body instead of destructuring these and then rebuilding an object the problem is I want to make sure that someone's submitting information is not sending any additional information that we don't need so I want to strip out everything we don't need just grab the stuff that we do and these things and then pass them along in the variables so then it looks like instead of create link I'll probably want to update this to update link and then I'm renaming that variable to updated link and then we pass in the variables and the query and then we return back the updated updated link okay so let's make sure we restart this we need to do that so let's restart and what we need is actually this entire object so let's grab one of these not that it's not popping open it's one of the nice things about reacts with the library loading server but when you don't need that landing page to jump up it's kind of inconvenient so inside of here we actually want to pass this entire data piece of data this entire object and again this includes an ID and this should be update link and I'm not gonna do any specific checking but I want this to be a put request so usually your updates are either put or patch I'm gonna make this a put request although I'm not verifying it on the backend anyway you could add that if you wanted and inside of here here's all the properties and let's just say james website updated link so we've got the name has changed here too updated link and let's just give it a shot let's test this out hopefully Oh something went wrong okay fair enough so let's see what we got here update link expected value of type ID but value is undefined okay so let's look at the link query again and this updated part actually we pass in the update link takes the property of regular ID instead of underscore ID I wonder if this is let's check this so update link and inside of here yes just it's just called the regular ID here not actually really sure why that is but that's okay so we'll make sure to rename in our update when we get the ID we will then rename this thing to ID this is a neat little trick in here and then we'll pass the actual ID property no underscore so let's see what we got let's refresh this Auto refresh did you catch that did I talk about that with an L if I def pretty sweet I will do another sweet so that looks like it worked now let's do our query inside of here again and we'll see updated links or update is working what that's cool so lastly we need our delete and I just copied one of those IDs and I'm going to I guess I just copied all this stuff again let's come into delete link let's update the update link let search for that and let's replace it with delete link all right so let's save that and in the return information coming out of here or actually the request mainly is gonna be a little bit different so from from here we want to grab the ID property actually we'll just well from the front end we'll just pass this in as regular ID so we'll grab the ID property from the body so json dot parse event dot body alright and then i think we got an extra line there we don't need actually we do need variables because we still we're gonna pass in that ID so we'll pass in the ID here and then i thought did we not update maybe we didn't do this let's now do it now we've got delete link instead of update link and so we'll pass and delete link query and then we'll pass back the or passing the variables as well and then what comes back for this is from this is delete delete link because that's the name of the mutation and then I'm going to call this deleted deleted link ID and yeah that should be fine so let's just let's just return back an object with an ID of and actually we'll just call this oh no that's fine so we'll return back an object that has the leading link ID so we should delete the link we send the query we pass in the ID that we want to delete hopefully that thing will delete it it will give us back the delete link property which is an object of an ID oh actually it already is an object that has yeah it should be yeah that should actually already already be something so let's just call this deleted link because that thing is already an object and then we'll just return that thing let's see it deleted link like that all right but remember we added the new function although it we already created the file so maybe it already knows about it anyway we'll restart nullify dev just to be sure that delete link is coming up okay and then what I want to do is come back to post mam we will do a delete request and we'll send in an ID like this this is regular ID I know these are kind of confusing but this is regular ID and we'll send a delete link and call delete link and send ID comes back if we then query back in our browser we should see one last link one last link sweet we're able to delete links that's cool so now we've got all of the crud operations in place one of the things you might want to do I'm gonna copy this over cuz it's not super important but if you wanted to enforce that people are using the right HTTP methods inside of your code you could do something this so formatted response so you could say if this HTTP method is not delete then send back an error message that says that this method is not supported so you could do that for this one you could do the same thing for the update in here so you could check it like this and say if this isn't a put say method not supported so you can go and add some extra things in here but all of our service functions stuff is working to do crud operations with Fawna DB and again all of this started if you remember from the actually I guess I don't have it in here let me grab it again from this other side it is that links graph QL file so we created or you created a database inside a fauna DB and then all you did was add this graph QL definition and boom you've got an entire database where you can go and do all the crud operations that we needed to pretty sweet I think so we'll take a second and just kind of think about how cool it is and then from here we've got all the information that we need we can kind of close out our back end and now we can work in our Funt front in front end but our front end and let me grab let me think for a second what all we need to do in here inside of the front end we're gonna use bootstrap so we'll just an install bootstrap there and let me look at what else we might need we need bootstrap and we already have Axio so we can use that and I think that's it that we need on the react side so let's install those things and I'm gonna open up the app J's file so we're not gonna get too much into like structuring our code and stuff in here not gonna think too much about that what I am going to do is I get rid of all of the boilerplate stuff in react I don't need a logo there I don't actually need the app CSS we can get rid of that too and then inside of here I want to start off with a container and then let's have we can add some extra padding now these are bootstrap utility classes which are pretty sweet so py5 is going to add padding of the why the vertical axis of five REM I think is what it becomes and then I'll add a title in here with a couple of classes of text center mb5 mock margin-bottom five and then we'll call this list Oh links whatever it is it doesn't really matter and then I'm gonna put actually maybe I'll I was gonna say put a couple of comments we need to grab all of the links we need to display all of the links and then add delete and archive functionality that's kind of what what we're gonna be doing in the front end cool so that works the one thing we need or the first thing we need to do is go ahead and grab all of those links and we're gonna use a use effect hook we're gonna use hooks inside of functional components inside of react so use effect will allow us to decide when we want to go and load the links when we start the application at least to start and then the you state will be able to track those links inside of state as you might imagine so let's do import from react and then we'll import to use effect and use state and inside of here we will I create a function let's create a load links function it's an asynchronous function and it doesn't take any parameters and what it's going to do is just make that request to the backend that we just created so it should make a request to API slash get links cool inside of here I'm actually just using the fetch API we can use Axios here but we could just use fetch since it's built in to front-end browser JavaScript so we will a fetch fetch slash API slash get links alright that's cool and then from that response we will get links and then we'll say a wait res days on so res that J someone will take that response and it will convert it or get the body object out of it by converting it to JSON and then let's just start by logging out these links oh but what so we've defined that function now we need to actually call it using use effect so this thing will be a function that has zero dependencies so this dependency array is when this function should be triggered based on something inside of that array changing we pass nothing so this will basically just run one time at the beginning of our component and then we'll call load links all right we'll just call that function and to run all of this again we run the fi dev because now if I dev will run our service functions as well as our front-end and it looked like that I have an air in here four or five four four oh this is just kind of information okay that's fine on inside of here say res that JSON is not a function that's because we didn't actually call fetch on this thing we just passed it a URL and we actually need to call fetch so fetch is built in the JavaScript we should see this thingy and let's get out of here go to our console hopefully we see an array of one and we see our links we've only got one but at least we're able to see it so that's pretty sweet and I want I want this h1 did I grab I would have thought that text center would have centered that thing but it doesn't look like it is and I don't think this is picking up bootstrap let's see it's out of here did we install bootstrap we did oh I think there's one thing we need to do inside of our index J s and that's to actually import all of the bootstrap CSS so let's go to index file and then make sure that you import all the bootstrap CSS now they also have like bootstrap components I'm not getting into all that and you can look into that if you want I'm not not worried about it we're just using regular boot shop classes here now this should look a little bit better so now we can actually go and start to display these things and to keep track of the links we need to have a piece of state for them so to use you state you do this so links and set links equals you state and we'll start off with an empty array so we're calling you state which returns back an array of two things the first is like the property itself the second is a function to call to update it and then you pass it the initial the initial value which is just an array so what we'll do is we'll set links to the links they come back there so we'll do that and then we don't need to log it out anymore and that should be our load links now we could also surround this with a try-catch so just a good habit to get into if something goes wrong we could log out whatever and that's kind of it you do more like probably display an error to the user or something but for now I think that's good so now inside of our our app we want to display these links so I'm going to create a link link list component that we haven't created yet but I'm gonna go ahead and import it so import linked lists from components directory and then link lists so inside of here we'll create our components directory this should actually be inside of the source directory here and then inside of there will create our linked list j/s I've got some snippets to do a react functional component you should check out those snippets inside of vs code and here it is so inside of here we want to pass a an object called links and then we actually want to like iterate through each of those links and display the different pieces of information that that we need so inside of here we'll have let's see I guess we'll yeah we'll just walk through I want to I want to differentiate between links that are archived and not so I want to separate those out but for now we'll start by saying h2 and we'll say these are the links and we can add a little bit of classes to it so we'll just add some vertical margin so we'll do that and then we'll say if there are links then we'll iterate through so link stop map and for each link what do we want to return well we want to return a div with a class of card and then inside of that we want to actually display each of these things but what we could do is we could even get a little fancier and we could actually display a link card component like this and let's import that we haven't created yet but we will use a link card a component import it from link card and now let's go and create that thing so we'll have our link card j/s RFC for stubbing out a react component and inside of here is where we want to actually display this thing so we'll have a class name of card and this component will accept a property of not card but link and then now we want to actually display that thing so we'll have a display of card then we'll have a card header the card header will have just the link dot name so that'll be the header there and then we'll have the card body alright inside that will have the link description and then we will also have an H ref that's going to point to link dot URL and then this is actually we just say the text it's gonna be linked at URL as well so we're displaying the name as the header the link itself and the description in the body and then inside of the card footer we want to have two different buttons one for archiving a link and one for deleting so we'll say a button with a class of button and button warning and margin right - it's kind of fancy stuff using Emmet inside of es code so you can type all this stuff out if you want to but I would recommend trying some of these snippets are pretty cool so we'll have an archive button and then we'll have a button with button and button danger all right yeah button danger and this thing will be the delete button all right so there's how we display the card now from our linked list we want to call a link card that looks right why is that giving me an error for each one of these we want to have a link card and we want to pass in the link itself like this what air is that giving me we don't actually need these brackets I don't think so it should be an implicit retirement all right so for each one of the links we want to return a link card and then we can also say the key something you have to do in react is the link dot ID all right interesting let's see how far we are down here so we've got our link list and we'll pass in the links and pass it in like that and is that right and linked list yeah we pass in links yeah let's see if that works whoa it worked so here's our one link we're able to pull all of that information inside of our app j/s we're able to pass it in two linked linked lists not linked lists and then display all of those links by using a link card for each one of them now from here one of the things we want to do we want to actually add the functionality for this archive and delete button and those are kind of interesting for each one of those they need to make a request to the API to be able to archive and delete so we'll create an archive link function and this thing will need to like I said make a request to the API to actually archive it so we'll pass in actually we have a reference to the link already so we'll say we'll grab that link and we'll say link dot archives archived equals true so we'll basically just archive that object and then we want to send that thing to our back-end so we'll do a try-catch you will snip it there and we'll use the fetch API again so fetch and then that's our just /ap I'm slash update link and then here we can figure how we're going to send this request so the first thing is we define the method of put and then we say the body is json stringify of that link so we send that in as the body and actually I think we just sent it in that way let's look oh this should be an async function let's look in our update link this should just grab the body directly yeah so we'll pass in that link and if there's an error again not really doing a whole lot here other than just saying Ah err whatever error oh this is spelled out all the way so archive link is just going to update the archived property of that link and then send it off to the API to update it and then the other one is going to be constant link and this is going to be an async function as well and for here what we want to do is we want to say Const ID equals link dot underscore ID so we get the ID property and then I can I just copy this y'all okay with that if I just copy all of this stuff and we'll make the request to delete link and we'll make this delete and we'll pass in think we'll need to pass an object that has a property of ID and cool so that should make that delete request to the server this function that we created earlier now we need to wire each of these up to our buttons so on click on click is going to be archived link and then delete link all right so that's cool we've got our archive link and our delete link those should be wired up now the thing that we're not going to actually notice though is or maybe we won't notice is the actual update so what we want to do is inside of our app j/s anytime or from our link card anytime something is updated or deleted we want to tell our app Jess to refresh those links so this is gonna get a little bit ugly I would probably use like the contacts API to make this a little bit simpler but we'll call this we'll pass in a function to refresh or two linked list called refresh links and this is going to call inside of our fjs the load links all right so then inside of our link list this is going to get refreshed links which we will then pass to the the link card and that'll be the same property so refresh links and from the link card we want to accept the the refresh links oops not that here so that will be a property that comes in and then after we archive and after we delete we want to call the refresh links hopefully that makes sense that's a little bit tedious I think again I could optimize this a little bit but we're just trying to say after we update or archive a link or delete a link just go back to the front until it's refresh alright another thing I want to do and no this is getting to be a lot is inside of the link list I want to separate this into links and archive links so I'm going to copy and paste this and this bottom one is are carved links and right in line here we can do a filter on our links and for our filter this top one we want to get ones that are not archived so for a link we want to return link is not archives and then on the bottom if you're not familiar with like a ray filtering map filter will return back a new array which you can then map over to display stuff so I want to do the same thing here except this should be if the link is archived so and then we'll call it dot map whoo all right we're doing a lot here so inside of here we see we've got our links we've got one and it is not archived and then if we press archive hopefully what happens is it actually went in archived and now it updated because we triggered back in the app j/s to refresh all of our links now we see our archived links as a separate list pretty sweet and then hopefully if we delete a link we should see it went away completely so all of that is working the only thing we're missing now is to actually create a link so let's go into our component and let's say link form Jas and stub this out RFC and I'm gonna put this thing inside of a card as well and then I'll have card header is add link and then the card body will be the actual form and we don't need an action there all right this is not necessarily a react tutorial so I'm going to cheat a little bit and I'm gonna grab the form that's already created because this should be this is not really the focus of what we're doing but for this form inside of it we're gonna have an input and this is using like form groups with bootstrap classes and stuff but inside of this we're gonna have a label and input for the name here I'll label in an input for the URL I'll label in an input text area for description and then we'll have our submit button I think we got this div should be closing form tag does that look right no that should sorry that one should be the closing of the card body and then we have the closing form tag does that look right maybe not oh this thing should have been a form from the beginning I don't know why that wasn't so I think these this one should now be a div did I get how am I still not right on these tags all right let's look so here is our form and card by that looks okay oh it looks like I just mistyped that one so that should be closing div there all right so there's our form again don't worry too much about the react part of that it's just kind of it is what it is and I'm gonna copy you a couple of things additional to this Oh actually we'll go ahead and type them out so we want to use the U state so we want to track the state here and we want to have one for name and set name equals U state it's gonna start off as an empty string then we'll have a couple of different properties one for the URL empty string as well and then we'll have the description just script shut if we can spell it and the description right here and that's gonna start off as an empty string as well and then I've got a a reset form reset form function equals to just reset all of these values so after we submit we'll reset all of these things to empty values and then I set URL all right so there's the reset form function and then we want our constand 'l submit like this this is going to take in an event and the first thing we do is call a diet to prevent default all right so there's the start of it and if you look in here notice that I've already wired up the value in the unchanged so this will make sure that we're tracking each of those properties inside of react now what we want to do is actually send the body to our API so we'll grab the body by combining the three properties name URL and script all right and then we'll do our try/catch and we'll use the fetch API to go ahead and send this stuff over to our server list functions so we'll say kant's rez equals a weight fetch and then we're sending this to API slash create link just our regular endpoint there this will have a method of post and in the body will be the string if I'd version of our body all right and hopefully that thing works we need to mark this as a sync and if it does we actually want to do a similar thing to what we just did inside of our other stuff we want to call refresh links like this so we'll need to one get rid of the semicolon because I didn't go there but we need to accept that as a property refresh links and then right before we do that let's actually clear out the input so we'll call reset form all right hopefully this form is working then we need to come into our app j/s and let's use this thing so here's our list of links we'll start up here with the link form I'm gonna get some intellisense here from vs code and then let's pass in the refresh links equals load links whoo all right let's see what we got now so here's our form we'll say James website HTTP ww1 ww2 quick dot-com this is the coolest site ever hopefully what we'll see is this just submit it should submit successfully wipe out the form and then add a link to the list of links below so submit ich sweet that looks like it worked let's actually grab the net liffe eye server list functions cheat sheet let's do this now Phi functions cheat sheet I've already done this once there it is this is an awesome cheat sheet submit this now it should come down to links again and we can archive one of these and it should come down here we can also delete it it should go away completely and it looks like all of our crud functionality is working in this jam stack application which we can now set up to deploy to netwo five now the only thing I'm gonna do here is inside of net Lafon I've already got my repo created so I'm not gonna use this existing repo but what you would need to do is add this to a github repository so connect this to github once you do come to net liffe I and we're just gonna create a new site here a new site from git and github and then this will go and make sure that you're able to do that so yeah you're okay to go to github authorize and inside of here now let's say what did I call I can't remember what I call the original source code build a full-stack app with Reax herbalists and faunal DB we'll grab that thing when we run this our when we deploy what we want to do is run the npm run build command and this will be a build command for react so just do that run and then actually I need a double check when we run the build command where do those files go so the output of that build command goes in the bill directory you can see that popped up up here so that's where we want to serve our stuff from this build directory so we want to run this build command and then serve the files from the build and show advanced we also want to add environment variables so inside of notify so let's grab the dot env file grab your fauna secret key you should have it in your DMV file let's add that value in here and let's call this fauna secret key so there's the the one environment variable that we need works well in nullify to add those and then let's just deploy this thing and what this should do is it should go and grab all the latest source code from your github repository so make sure you connect your code to github create there posit ori connected and then add a like commit are push all of your changes to github what this will do is it will go and grab all of those files it will run a build react build to grab the output of those files and it will take those and it will host them and it will also grab all of the functions out of the functions directory for you use so I'm gonna pause here and we'll let this finish up and then we'll come back and take a look so actually this just finished and we had an error this is actually new for me so I figured I might show you and it looks like react is treating warnings as errors when the CI property is set to true so continuous integration that's kind of the automated process that all this stuff goes through so what I'm gonna do is from my other monitor on the original source code I just pushed it to the github repo what that should do and you'll see this from now on is when you push your code it should trigger another build inside of nullify so we will see one thing to actually show you here is it says different functions path detected functions versus nothing in the notify you I so inside of that net Lafitte AMA file that we created so that we could help run stuff locally when it gets deployed net Liffe i will look at that file and kind of figure out what to do with it in terms of how to host and where your functions and things are so it's doing that for us it's detected that thing which is really nice and I'm gonna let this build finish and see if this one works and see if we're good to go alright so that just took a little bit to finish it says to me actually hopefully you see the same thing site is live so it did the react build its hosting those serverless functions and hopefully what we'll see is inside of the site which we can go to notify gives you a random name that you can use brave new man something-something all right and when we open this up it looks like it's not working because we don't see the links coming here and actually if i refresh just to show you this when it makes a request to the get links endpoint that actually seems to fail and i think this is a little bit of a weird thing i haven't quite figured out so i'll give you a way to fix this but the redirects that we set up to use that slash api for some reason aren't working when deployed inside identify so what we're gonna do is go back in the source code and change our reference in react from slash API to slash Delphi slash function so we'll just go back through and update it that way and then redeploy and hopefully we should be okay all right so I'm gonna go inside of vias code I'm going to close all these out and I am going to just do a global search in here for slash API and you'll see we're doing this in four different locations here here here and here so what I'll do is I'll just do a global replace so instead of slash API I want slash dotnet Liffe I slash functions and then that should be good so let's go ahead and update all of these and I'm gonna get this up and running again just to make sure these are still working so I'm gonna run this again locally make sure it's working and then deploy this and then we'll see if it's actually working when deployed so this should pull up a link okay there we go so that looks like that worked so I'm gonna check all this stuff in and then deploy it and we'll see if it works all right so that look like it's finished that build looks good let's go back to overview I'm gonna open this up again actually it should already be open and I'm just gonna refresh this page hopefully now it was successfully make a call to the backend and you can see that my Nana five functions cheat sheet link is here I can archive that thing hopefully there we go and then I could go in and delete it as well so we got all of the functionality crud functionality inside of reacts using our service functions inside of neckla file we've got this hosted did I mention that you can take this URL and share with anybody out there that you want to this is probably one of the easiest ways for you to build a really nice portfolio object that you can have a hosted out and met with I have back-end functionality with serverless functions and get to experiment with some new and cool technologies so I hope you enjoyed it thanks again for sticking around for a longer video and I'll see you in the next one
Info
Channel: James Q Quick
Views: 28,225
Rating: 4.9873819 out of 5
Keywords: jamstack crash course, jamstack, react jamstack, netlify jamstack, netlify static hosting, netlify functions, serverless functions, netlify tutorial, jamstack tutorial, react course, web development tutorial, web development 2020, faunadb, faundb graphql, faunadb tutorial, faunadb netlify, faunadb serverless, serverless javascript, fullstack web development, fullstack application, javascript, build a jamstack site, what is the jamstack, what is serverless
Id: 73b1ZbmB96I
Channel Id: undefined
Length: 74min 53sec (4493 seconds)
Published: Tue Jul 07 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.