Can URQL replace Apollo Client? URQL tutorial with SSR and SSG in under 20 minutes using Next.js

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hey how's it going everyone it's lee halliday and today we are diving into urkel which could be a replacement for the apollo client so it's not as popular as apollo if we look at npm apollo's got 1.1 million weekly downloads oracle's only got 128 000 but the cool thing is if you go into the bundle size urkel comes in weighing 7.5 kilobytes while apollo is way up there at 33 kilobytes so basically if urkel does what you need it to do which is pretty much most of apollo it could be a great more lightweight replacement so we're going to talk today about how to set it up how to do client-side queries and then since we're going to be working inside of nexjs we are going to cover server-side rendering and static generation using the get static props function so let's get started here's our app it's running on localhost port 3000 and it's just saying home right now so if we pull up the code base i just want to show the dependencies we're working with first i've only installed two outside of the typical next.js setup that would be graphql and oracle itself so first what graphql api are we working with i'm i've pulled up here in my graphql playground we're using graphql weather api dot herokuapp.com it's just a simple graphql api we can connect to and here i am querying the city weather where i live right now toronto weather where we're asking for the the summary of the weather the temperature and we're passing in one variable here city of toronto and this is what we get back so that's the data we're working with so moving back over to the code what we're going to get started with is actually setting up the oracle client that will be the first step so i've already got the imports here seems like a lot of them but it's not so bad once we get going so because we're going to cover server-side rendering at some point later in this video i'm going to set up this client now to support it even though we're not going to use that functionality right off the bat so we're going to start by creating a variable called is server side and we're going to set this by looking at the type of window so if it's equal to undefined that means we're on the server because there's no there's no window on in node i guess so that's that's how you do that and next we are going to set up the ssr cache so ssr cache and that is equal to ssr exchange where we have to tell it whether or not we're on the client or not so we can just say it's the not of is server side this thing here will be in charge of basically recording the queries on the server so that when we get into client land it doesn't have to re-execute those same queries but forget about that for now we'll come back to it later so now we're going to set up the instance of the urkel client itself so this will be using the create client function and we just have to pass in a few things we have to pass in the url that we're connecting to so i'll just pop over here and copy that paste it in and then we're going to set up something called exchanges and if you've worked with apollo client before to me this is most similar to what they call links it's sort of like pieces of code that can intercept and modify the outgoing graphql request and sometimes stop it before it actually goes out on t and onto the internet so we're using a few exchanges here the first one is the d-dupe exchange um i assume this is if you're querying the same query twice it dedupes them so it only passes it to the server once then we've got the cache exchange no next we have the ssr cache and then finally we have the fetch exchange uh in apollo links it's the same way but the last link or the last exchange is typically always the one that goes out across the internet and makes the actual fetch request so that's setting up our client we're not going to use this next thing i'm going to show but just if you needed to pass credentials in headers and stuff like that you can do that by passing a function to fetch options where you can return things like the headers so we're just going to leave it at that we're not going to add any additional headers but this is how you would add like your authentication header or authorization header whatnot so with this setup we are going to export both the client and the ssr cache because we are going to need that when we move into the ssr territory so with our client set up we basically need a way to provide this to the rest of our application and that index.js is done in the pages underscore app component which wraps around every single page of your application and we're going to import provider from oracle from the package itself and then we're going to import the client and the ssr cache from this uh file we just set up creating the oracle client so let's wrap the provider around our page the component like that and we need to pass the client as the value prop to our provider that's it for now we're not going to touch this till we get to ssr but this will basically provide our client to the rest of our application so now we can move into the page itself which right now is not doing very much it just says the word home inside of a pre pre-tag so we're going to start by uncommenting out those two imports so we're using a use query hook so very comfortable if you've been working with apollo client before and we're also going to access the client in the ssr cache as well from the the file we set up so the first thing is we need to declare our query so we're going to say const whether query is equal to backticks so in a paul client you're typically used to using gql here it doesn't seem like you have to do that with urkel so we're going to leave that off and i'm going to go back over to this graphql playground and just copy and paste this query so why don't i just cover this query quickly what we're doing is we're saying to graphql we're going to do a query as opposed to a mutation or a subscription and we're going to give a name to that query toronto weather this could be called whatever you want it's up to you and we're saying we're going to be passing in a variable called city of type string it's required with this bang here and then we run the actual query get city by name where we pass in as a field here the variable value city and then the rest is just the different fields we're going to ask graphql to give us so with this in place we can move down into the the component itself the home page and what we're going to do is we are going to say const result is equal to use query and um this is a little bit different than apollo what you do is you pass an object in and you say okay my query is weather query the variable from up here and my variables are city of toronto just like that so inside of result is where you get the data or whether it's loading or whether there's an error so we'll say here data loading and error and we'll just grab that from the result object so now we can do our handling like if loading return loading if error return [Music] error oops just like that so that means if we get to this point here we know we have data and we're done loading so what we can do is um inside of these braces we're going to use json.stringify data no replacement spacing of two so that is um setting up our query just making sure i didn't miss anything here i was like i haven't used these things at all yet what's happening it's because those are going to be used later in the ssr portion so let's hop on over to the web we can already see here that we have our data on the screen if i refresh um so quick you don't even see the loading text but it is good to go just like that and we can go in here to the network tab and we can query refresh the page and we can see that it's making this fetch request over to this graphql api so that is client-side oracle pretty easy to get set up and it's almost just as easy to add in server-side rendering so they do provide a next urcle package and i was looking at it and after sort of understanding how it worked i sort of realized it's almost just as easy to do this myself and just using sort of the base oracle package so that's what i'm going to do but feel free to check out next circle if you'd like i just found it almost pointless because it's it's so easy to get up and running so we are going to export our async function called get server side props so in here basically our job is to perform the queries on the server that would be run inside of our component here so we're going to await for the client so that's why i imported the client here so we're going to wait for the client to perform a query and we're going to perform the weather query and we need to give it the variables that's the second argument passed to this function so this would be city of toronto and at the end we have to say to promise i don't know what it is when you don't do that but i guess it's not a promise so we're going to wait for this client to finish and the funny thing is you don't do anything with the result of this query yet basically what you do is you come here and the job of get server side props is typically to return props that will be passed into our um component our you could receive them here so any props that you return from this get service have props you could receive them here so that you can then render your component server side but what we're going to do is we're going to return that the props but the proper going to return is called urkel state and let's um grab that so where does it come from it basically comes from this ssr cache that we set up so you say ssr cache and then you call a function called extract data just like this so if we were to refresh the page will it work and the answer is no so undefined cannot be returned so i screwed up oh that's what i screwed up refresh there we go so it's still executing the query as we can see here so it's not fully ssr yet we're sort of missing a step so what do we do with these props the urkel state that is returned from our get service hyprops function what we're going to do is go over here into the app so this is remember it wraps around every page and we're going to start but just by console.logging the page props so we can see what's inside of them so if i go into the console let's just clear that out refresh the page warning did not expect server html to contain text okay so this is my bad i think um i don't think you can just return that you have to wrap it in a component so that means we don't need that so i'll just fix this as well say error refresh hopefully oh shoot what did i mess up did not expect server html to contain text node so i've done something wrong so get city by name in pre uh you know what i think the issue is right now it's basically whatever is rendered on the server it's expecting the client when it first renders to to match the same thing that the server rendered so right now it's saying like i've got a mismatch between them that's my theory anyway we'll see if that's true once we continue so it was not that this has to be wrapped in a div so sorry for wasting your time but what i actually wanted to show is what's inside of this urkel state so we'll take a look at that and then we'll see if we can get this error or this warning fixed in a second so what you can see here in oracle state is basically the data that was returned from that query so our next step is basically we need to take that data that was returned from get server-side props as oracle state and then when we render client-side it's patched in as a page prop and we need to basically take that data and stick it back in the urkel client so that when it goes to query this data on the client it sort of realizes oh i already have this in my cache i don't need to go out on the internet and re-query it i can just use the the data that i already have so we'll do that by saying if page props dot oracle state so if there is some state we're going to access our ssr cache and we're going to call a function called restore data where we basically just pass in the page props dot oracle state like that so if i clear this out let's see if my error goes away let's hope okay it does so that's that fixed that one problem basically whenever you do ssr the server has to render the same thing that the client originally renders otherwise it it wants them to be same and it doesn't like it and it gives you warnings but let's go into the network tab and refresh and this time we don't see any http query http requests going across the internet because it's reusing that cache that we generated on the server and then restored in the client on the um on the app on the on the page the my app component that wraps everything so at this point we have done ssr we're going to copy this comment it out and we're going to actually show how to do static generation so i'm going to paste this in and i'm going to say get static props so what's the difference between these two this executes on the server during run time so every request that goes in it's going to be executing this query but say the data doesn't change very often and you want to instead generate it statically at build time so for that you can use get static props instead so when you build this app and put it on the internet it will generate the query once and then it will just reuse that static content sort of more like how gatsby functions and honestly you don't have to even change anything at all here just the name of this everything else works the exact same so i can refresh it's still not executing the query but what you could do here is you could pass in another one called revalidate let's say every 60 seconds so instead now what this will do is basically will reuse the same data for 60 seconds then it the next request comes in it will run it once to regenerate the static content and then that will be valid for another 60 seconds so we've essentially implemented a 60 a one minute cache so which i think for weather is fine because it's not changing every five seconds and with that we're done so basically we covered how oracle can be a great replacement for apollo it does 95 or more of what you typically do in apollo i don't think it does like um you know apollo can do like local state which i think is sort of weird anyways but oracle can't do that and in my case that's fine because i don't really like using that anyways i prefer to keep my server-side state separate from my app local state but what we covered is basically how to set up the oracle client using these exchanges and how we can override the headers that are passed with each http request then we took that client and wrapped it around each of our pages as a provider so that we can access functionality that it provides such as executing queries using the use query hook we checked if loading error and finally we rendered this data and then we covered how you can basically go the next step and support server side rendering and static generation ssg and then you can add that revalidate 60 seconds to turn it into a cache that gets invalidated once a minute but the props that are returned from both of these functions here you basically need to intercept them and use them to restore the data in the ssr cache so if we were to go back and look at the oracle client each request that you make it sort of goes through each of these exchanges so it's going to go through dedupe then cache then ssr cache before making an http request so basically i don't know if it's the cache layer or this layer but either way it sort of realizes oh i already have the data for this query i don't have to keep going to the fetch exchange i can just return the result immediately which is accomplishing not actually performing queries on the client hope you enjoyed this video i just wanted to mention two things if you're liking this content i produce react and javascript videos weekly so please subscribe hit the bell so you get notified like this video if you did in fact like it but i also wanted to just quickly mention that i launched an xgs course you can find it at next.leehalliday.com and we build a full stack next.js application using in this case apollo client graphql maps typescript prisma to do databases so it's really cool check that out it's a great way to support me and the channel have a great day bye
Info
Channel: Leigh Halliday
Views: 4,745
Rating: 5 out of 5
Keywords: urql vs apollo, urql tutorial, urql server side rendering, urql SSR, urql SSG, urql nextjs, urql graphql
Id: Miock1yWkCQ
Channel Id: undefined
Length: 19min 49sec (1189 seconds)
Published: Thu Mar 04 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.