Building full-stack GraphQL applications with Hasura and Vue 3

Rate this content
Bookmark

The frontend ecosystem moves at a breakneck pace. This workshop is intended to equip participants with an understanding of the state of the Vue 3 + GraphQL ecosystem, exploring that ecosystem – hands on, and through the lens of full-stack application development.

Table of contents
- Participants will use Hasura to build out a realtime GraphQL API backed Postgres. Together we'll walk through consuming it from a frontend and making the front-end reactive, subscribed to data changes.
- Additionally, we will look at commonly-used tools in the Vue GraphQL stack (such as Apollo Client and Urql), discuss some lesser-known alternatives, and touch on problems frequently encountered when starting out.
- Multiple patterns for managing stateful data and their tradeoffs will be outlined during the workshop, and a basic implementation for each pattern discussed will be shown.
Workshop level

NOTE: No prior experience with GraphQL is necessary, but may be helpful to aid understanding. The fundamentals will be covered.

116 min
19 Oct, 2021

Video Summary and Transcription

GraphQL is a powerful tool for building APIs, offering flexibility in data retrieval and real-time functionality. It simplifies API documentation and enhances development with type checking and code generation. Hasura is a popular GraphQL engine that supports subscriptions, permissions, and database integrations. The Workshop covers topics such as setting up GraphQL APIs, handling permissions and security, integrating authentication, and using GraphQL with Vue.js. It also discusses various libraries and tools for working with GraphQL APIs and state management.

1. Introduction to GraphQL API

Short description:

We'll cover the comparison between RESTful architecture and building GraphQL APIs. GraphQL engine by Hasura allows you to create a unified data graph by spinning up a real-time CRUD API with auth and other features. It's open source. In a REST API, making an API call requires multiple calls and can lead to complex API architecture. GraphQL solves this problem by automatically providing the data you request.

So, um, we'll try to go at a moderate pace. Again some people might be super familiar with this, others not so much. But, uh, yeah, we're just gonna cover this. So there's a couple of really awesome things about GraphQL API, GraphQL and one of them is the ergonomics of the API. So this is basically going to walk through, um, RESTful architecture in comparison with building GraphQL APIs, which I think is something that everybody will be able to draw parallels sure we've all built a CRUD app, uh, in our lives.

So I am a technical evangelist for a company called Hasura. It's GraphQL engine. Um, really cool. You basically, uh, it allows you to take a data source, so that could be Postgres, could be MySQL, SQL Server, it could be other APIs that can be REST or a GraphQL and it's sort of spins up an automatic real-time CRUD API with auth and some other neat stuff on top of it and lets you provision permissions, uh, and join data across data sources as if it were just one big, uh, unified data graph. Uh, oh, and it's also open source.

So uh, we'll talk through an API call. So in a REST API, when you make an API call, right? Um, you do something like get API, slash user, and you pass an ID and you'd get this, uh, HTTP response. Uh, let's check in. Sorry. Does anybody have sound? Sorry, there's like a ton of messages. Uh, does my audio work for everybody? Yes. Yes. Okay. Okay. Thank you. Thank you everyone. Um, okay. So yeah, so you have some app, uh, and your app is going to make a call to an API. I get requests might look like this and it's, it's going to return an HTTP response, right? Some, some Jason that looks like this, right? So we have Elmo. If we want more info, right? Like, so what if we want Elmo's, uh, addressed, then we need to hit the address API and we need to give it the user ID that we just asked for over rest. So that's two API calls. And that only gets worse. Um, and you can parallelize these API calls the rest, you can batch them. You can make bespoke API's that return, you know, exact data shapes. But essentially this problem is going to remain no matter what you do because that's the nature of rest. So I'm gonna move this chat window.

If you think about a page, right? You're not rendering just an isolated entity. So if you think about a user and you're having a hierarchical data model, you're probably going to want to render that user. You might want to render their address, you might want to render their order history, you might want to render a list of friends. There's this cascading hierarchy of dependencies and interrelationships, and all these need to be resolved against the API requests. So let's say we have a problem, right? We get a new... Like a mobile app designed for a page and it's really complicated, and it would require like eight REST calls. So we go back to our API developers and they're like, hey... Could you just write me like this one special API call that returns this exact data shape? Because that would make my life so much easier. And so now you get this new bespoke API call, right? So they say, okay, fine, sure. And you get this user info API endpoint and then now you have Elmo and his address. So the problem is, if you continue to do this, what's going to happen is that your API architecture is going to turn into absolute spaghetti. And so you wind up with more and more of these bespoke API calls, or you're just having more and more cascading sort of like intermingled and hierarchical dependent REST calls. And so one thing that you could do is say, well, okay, you know what, I'm going to implement some kind of like fields filter. So I'm just going to ask for the fields that I want. And that works. It's a little bit of a duct tape hack, but it works. But with GraphQL, you don't have to do that. With GraphQL, the way that it works is the data that you want is automatically works is the data that you want, that's the data you asked for. So if you want elmo, you want his name, you want his address in the street, you just send a payload over the wire.

2. GraphQL API Basics

Short description:

API models are often graph-like, making relational databases popular. GraphQL allows for flexible data retrieval with control over the hierarchy. GraphQL is a specification, not a special technology, for handling API requests and responses. It uses a single endpoint and supports POST requests with query and variables fields. Mutations in GraphQL act as posts, patches/puts, and deletes. Query is for querying information, while mutations are for mutating data.

This is, Hey, I'd like JSON in this shape and the API says, okay, here you go. It's a little bit more complicated than that, but that's the premise. Um, and so there's a couple of key insights here. And one of them is that almost always your API models, uh, are somewhat graph like, uh, and this is why relational databases are so popular. Um, it's not very often that you find yourself, uh, writing entities that don't have some sort of relationship that are just flat models and disconnected from everything.

When you're traversing this data graph, um, you want to control the data that you get, because you don't want to, you don't want to, you don't want to pull this entire hierarchy of data. Uh, but at the same time you really want the flexibility to say like, uh, I need this model, but then also just like maybe one or two fields from a child or a parent model. Um, and GraphQL allows you to do that.

So the way that a graph, the way the GraphQL works is, uh, you have three operation types. So you have queries mutations and subscription subscriptions and, um, where he's, uh, queries map to the, uh, get verb, right. When you think about an arrest API, they fulfill the role of what would typically be used for get requests. So, um, this GraphQL query is saying, Hey, I want a user. I would like their ID name. I want the user's address, uh, relationship. Um, and I want the street, uh, from user address, right. So user address the street. And I want that to be only for the user with the ideas. One and kind of the way that this works under the hood, um, is, is not very, uh, there's not a lot of magic here. Um, so GraphQL is just a regular, uh, HTTP requests. So if you know how to make a post request or a get request and a pull request, using the curl or Postman or using the fetch API, you already know how to use GraphQL. Um, a lot of people think that GraphQL is some kind of like special technology or like protocol, uh, that you support, but it's not, uh, it's just a specification for how your API should deal with requests and responses just like REST.

And so the way that GraphQL works is you have a single endpoint and, uh, it takes post requests. Typically you can allow it to take requests, but it's unusual. And you basically just send a, uh, a fetch request to this API, that's a application slash JSON type. And there's only two fields, uh, that you need to put in here. So one is the query. So here's our query. And, um, this would just go in like a fetch, uh, a fetch requests, uh, body object in JavaScript. Uh, the other one, uh, that we'll probably see in a second is variables, uh, which will allow you to substitute an actual variable for things like the ID. And then the third one, uh, this is optional is giving it an operation name and that's mostly used for things like, uh, metrics, analytics and tracking, just for you to be able to tell what operations are being run. It's like, um, it's like an operation tag, right? So we send the graphQL query as a string in Jason to our API. And what we get back, uh, is just a Jason object that looks exactly like the, uh, query object that we sent, uh, in the request. So When he would write it to a rest API, uh, you typically make a post request to something like slash API slash to do, uh, you'd give it a to do, and then it would send this 200. Okay. And it'd be like, all right, man, I made this to do, and here's your new to do ID. Um, the way you do this in graph QL is you use mutations and mutations to fill the role of multiple HTTP verbs. Um, which we might see in a second. So mutations act as posts, mutations act as patch or put and mutations also act as delete. So, um, it might be obvious based on the name, but query is for querying information and mutations is for mutating, uh, data. So here we see some example mutation where we added to do, and it takes this a dollar sign is a variable. So we're saying it takes a to-do um, variable called new to do and it returns the ID. And then when we, uh, send this across in our HTTP request, the only other thing we need to do is give it a new variables key that has the new to do and the to-do we want. So, uh, you can see it right here is the new to do graph, graph QL. Let's back the slide. Um, now I want to go back. Uh, it's the same thing. So just take, take your post data and put it under the variable name and the mutation. And then again, you'll get this 200 response and it's going to give us this ID because ID is what we asked for. So, um, that might not be very intriguing.

3. Real-time APIs, Documentation, and Benefits

Short description:

GraphQL shines in real-time APIs with subscriptions, allowing reactive and real-time UIs. GraphQL simplifies API documentation and sharing, always staying in sync with the code. The schema definition language ensures everything in the API is documented. GraphQL's introspection ability enables self-documenting APIs. Type checking and IntelliSense in IDEs enhance development. GraphQL code generator generates typed code for various frameworks and languages.

So, um, that might not be very intriguing. Uh, you're like, okay, I can do all of this with rest already. It might not be as like fancy or snazzy as your, you know, little JSON shaped requests, but I can already do that. Um, one of the places where GraphQL really shines, uh, is in real time APIs. So, um, we'll cover this a little bit later, but, um, subscriptions are the third operation type and they allow you to, as the name implies, subscribe the data. So you could run a subscription and say, um, subscription, uh, uh, messages within the last 10 minutes. And then your, uh, subscription body would be like messages where, um, updated at is less than or equal, you know, date.now minus 10 minutes. Right. And anytime the database, um, has a new record that meets that requirement, you're going to get a real time push of the new data. And that allows you to build reactive, uh, and real time UIs super, super easily. Uh, and this sort of functionality for any of you who have dealt with building a web socket based, uh, applications using things like Socket IO, Socket IO, uh, is typically a lot of work in addition to your regular CRUD API. So the kind of way that real time APIs work before is, uh, you have one option, which is polling. So you just, you know, every X seconds, you're making this repeated request, uh, which is not the most efficient kind of grace. So the other option that you have is, uh, uh, web sockets and, uh, that allows the server to push the data to the client. Um, it, I don't know that it's necessarily like a nightmare, but it, it can get very complicated, especially when you have a lot of subscribed clients. Um, and you need to manage the connections properly. Uh, particularly things like back pressure, um, and handling like connect and disconnecting state. Um, so after, um, the way that it works in GraphQL is you basically point your GraphQL client or your web socket client to your GraphQL endpoint. Again, same single endpoint and you write your subscription. And so, uh, like here, we're saying, uh, I would like to subscribe to the order with this ID. And I want to know if it's been paid and I want to know if it's been dispatched. When that order is updated, uh, our UI will be immediately notified and we'll have the current, uh, and most recent values of paid and dispatched. And we can kind of do with that what we will. So another huge benefit of GraphQL APIs and, uh, maybe one of the biggest is how easy is, is to document and share API. So, um, I don't know how many of you work in startups, uh, or have, you know, tried to bootstrap, uh, you know, soft stuff, but, uh, the typical life cycle of dev docs is that the API developer, builds the API, the API developer writes documentation, which winds up in like Google sheets or like postman or swagger. Um, you read the documentation and then finally you start integrating the API, but the docs are missing, they're out of date, uh, or they're just wrong. Um, or the more realistic scenario is a API developer builds API and there is no documentation. Um, so with graph QL, the way that it works is that you build your graph, QL API, and that's it. Um, you or whoever it is that's responsible for the, the integration, whether it's server side or client side. Uh, cause graph QL works on both. And we'll see that today is you just start integrating it and it's always, always, always up to sync. Um, and the reason for that is because of the pipe system. Um, so we won't go too deeply into this, but a graph QL has its own little, like, uh, what they call SDL schema definition language. and it's a language for defining types, uh, for your graphic service and also, um, operations that you can do on a service. Um, if a type where an operation doesn't exist in the schema definitions, you can't write a resolver for it. So there is no scenario in which something would be available in API and not documented. Uh, the types look very similar to type script, uh, or, uh, SWIFT or like Kotlin or any other like post fix type language. Right. So the really neat part, uh, is this introspection ability that GraphQL has, which is basically you can tell GraphQL, uh, you can send it a special query and you can basically say, Hey, tell me about all the types in your API. Tell me about all the operations in your API. Um, and it's self documenting and then you can generate, you know, all sorts of nice like doc sites and like ERD visualizations. Um, nobody has an excuse of being too lazy to write the docs because they're just the types of there for you. Um, um, so this is the part where we're going to start building stuff. Um, there's a couple of slides I have after this. That's just accessory stuff. Um, I should have put this one at the end, so outside of this, there's some really neat benefits of using GraphQL so you can get type checking and IntelliSense and operations inside of your IDE. Um, and these can be run against a live schema, so it's kind of like having a typed schema docs, uh, at your disposal. Uh, and the other way that you can do this is to use cool as like GraphQL code generator, um, which can generate a typed code for a lot of different frameworks react, view Apollo, um, and spelled. It can also do backend. Uh, so it can generate SDKs that work in node, um, and even has plugins for things like C sharp and Scala and Java and Kotlin.

4. GraphQL Tools and Utilities

Short description:

GraphQL offers various tools for schema visualization, load testing, and documentation. GraphQL Voyager provides interactive schema visualization. Easy GraphQL load test generates load testing queries based on your schema. GraphDoc creates a searchable static documentation site. These tools enhance the GraphQL development experience.

Um, so it's, it's pretty cool. Uh, we'll also see this today and when you use these, they're all, uh, you know, uh, documented, uh, types. A et cetera, et cetera. There's tools like GraphQL Voyager, uh, which are a schema visualization tool that let you look at your types, uh, and your operations and you don't have to do anything. You just pointed out your schema. It runs, uh, introspection and then it can generate this, uh, interactive diagram. Uh, there's tools like, uh, easy GraphQL load test, which can auto generate queries to load test your GraphQL API. Again, using introspection. So you just run the tool, give it your GraphQL endpoint and it figures out, uh, queries to run, uh, that map to valid operations in your schema and we'll do a load test for performance on your API and then give you, uh, visualizations and diagrams that you can, uh, uh, view using a tool called artillery. Um, and then there's GraphDoc, uh, which again, you just, you know, run NPX GraphDoc. You give it the URL and you get this really nice searchable static doc site. Here's an example from Shopify. Um, yeah, so that's, there's a lot of really, really cool tools.

5. Closing Remarks and Conference Announcement

Short description:

We have a website called learn with tutorials for various stacks. If you're interested in learning more about GraphQL, we have great resources. We also have a discord channel and are giving credits for a managed version of our open source product. We are hosting an annual enterprise GraphQL conference with workshops and interesting stories from larger corporations. We'll now move on to a short content before coding. Feel free to ask questions or talk about anything. Thank you to David and apologies for any audio issues. The presentation is being recorded. Don't forget to check out our upcoming conference and the view comp shirt.

Um, closing piece before we start. Um, we have a website called learn, which has tutorials for a ton of stacks from like flutter to ELM to react to view. Um, if you are interested in learning more about GraphQL and building apps, we have a lot of great resources here.

Uh, we have a discord channel, uh, specifically if you're new to GraphQL, we have, uh, um, a channel for that. And for everybody that's in the workshop today, uh, we're giving a hundred dollar credits to a sur crowd, which is basically just like a, a managed version of our open source product that has some additional, uh, features around like, uh, analytics, rate, limiting security, um, stuff like that. Uh, you can see that info here, VueJS live.com slash perks. Uh, and the coupon code is here and then last little thing that I have to plug, uh, we are actually hosting, uh, our annual enterprise GraphQL conference, uh, here in a little bit on October 28th. So that's online. You can, uh, register at our website, that I am slash enterprise GraphQL. Uh, we'll have a bunch of GraphQL workshops and, um, the interesting part that we, uh, well, I guess one of the interesting parts is that, uh, there's some cool stories from larger enterprise corporations about the ways that they use GraphQL. Uh, and even though it's an enterprise comp, sometimes we have startups that speak too. So, uh, I always find it interesting to hear, um, kind of like case studies or like how other people are approaching this.

Um, okay, so with that one out of the way, um, we're going to go through this one that literally has like three minutes of content. And then I promise we will code stuff. Um, I, I hope that I am not boring. You guys, uh, guy, girls, gals and other folks. Um, please let me know if you have questions. I would absolutely love to answer any and all of them or just talk about whatever. Um, thank you. Thank you, David. Um, uh, I, thanks. I have a really hard time with these online presentations. I'm not used to them cause you can't read the audience. You're just talking to a screen and slot easier to do it in person. I interact with people. Uh, okay. You're not able to hear the audio can feed. Oh, I'm so sorry, man. Or not man. Um, is it something that I'm doing? Clicked the main sound is okay. Okay. All right. You Karen. Karen, you also can't hear the audio. Can we do a poll? Oh, oh, you can hear. Okay. Okay. All right. I'm sorry for anybody who can't hear the audio. I'm really sorry. I'm almost, I'm looking at a hundred percent of you. I'm almost, I'm like a hundred percent certain this is, uh, being recorded. So, uh, yeah, hopefully it should be available after. Oh, I totally forgot. Um, I wore my view comp shirt. This is the view comp shirt from view, comp New Orleans is the very first view comp. Yeah. I love you so much. I've been writing view since like late 2016. Yeah.

6. Sharing Vue.js Enthusiasm

Short description:

Will you share a link to your slides? I'm ride or die for Vue.js. Vue 3 composition. I love Vue so much. I used to speak at Denver Vue.js. Sarah Dressner is super cool. We're gonna move on to this little mini presentation. Justin Lee works for Red Hat on their Quarkus framework. You should totally get started with Vue. I'm sorry for engaging with all the people in the chat.

It represents. Um, okay. Will you share a link to your slides? Uh, yeah, yeah, I'll do that. Um, do, do, do, do. Select a spud. I'm gonna put the link in discord. So there's that one.

Also, this next one is recycled from my, yeah, Vue.js for the win, man. I'm ride or die, ride or die for like half a decade. I still love it. I thought that Web Dev couldn't get any better than Vue 2, I thought that was as good as it could get and then Vue 3 came out with the composition API and then Pana came out, you know, there is VueX and I was like, this is the, this is just, this is the epitome of what state management should be. Like, we can't do any better than this, we should just stop now. And then Pazfa came out with Pina and I was like, okay, all right, it's all right, it's a little bit better, we can do better. But we're going to see the, we're going to see the Pina, stuff and VueX V5, he's on the, he's on the board. Yeah, man, Vue 3 composition.

Okay, and then I'm going to share this one. It's like the one, it's like the one time of the year that I get to like unabashedly share my absurd enthusiasm for Vue. I love Vue so much. I've been writing it, I've been writing it for so long. All right. I used to speak at Denver, Denver Vue.js. I met Sarah Drastner, Sarah Drastner. She was at Netlify for a while. I think she's doing something else, but I met her twice at Vue.js Denver. I used to go there and I spoke a couple of times at the Galvanized and Vue.js, I used to go every month, it was a good group of people. Anyways, here's the other one we're about to go over. Sarah Dressner is super cool, by the way, she doesn't remember who I am, but that's okay, I don't blame her. All right, we're gonna present. Okay, so we're gonna move on to this little mini presentation. You want me to also share this? I can't pronounce your first name, but your last name's Peter. You want me to share this link in the chat as well, the Zoom chat? Oh, okay, thank you, thank you, Ivan or Yvonne. Justin Lee. Wait, is this the, wait, Justin Lee, are you the same Justin Lee that works on the Quarkus team? Oh, okay, does that happen often? Do you get confused with him a lot? Oh, yeah, that's maybe a sign that I have no life and I know too many random, obscure developers. Justin Lee is this really cool, he works for Red Hat on their Quarkus framework and he's the Kotlin guy on their team and he really loves Kotlin. Super cool dude. Anyways, but yeah, you should. You should totally get started with you, Justin Lee. Okay. Okay. I'm clicking on join audio if you wifi still can't. Candida, man, I am so sorry or if you're not a man. I have a really bad habit of just saying man. I mean that in a gender neutral way. If you want, you can also just private message me I'm on discord and I'll make sure to get you the recording or whatever you need. Yeah, Jeremy you work for the DOE that's at the Department of Energy. That's awesome. Okay, I gotta stop. When does the real stuff begin? Okay, I have to stop engaging with all the people in the chat, I'm sorry. You are all great people and I really want to talk to you. But some people also want to do stuff.

7. Impact of Generated Types with GraphQL

Short description:

GraphQL code generator and TypeScript have revolutionized the developer experience, enabling schema-driven development and auto-generating type-safe consumer code. These tools generate types for specific operations and dynamically calculate the return type queries. This eliminates the need for manual type definitions and enhances productivity. Tools like GraphQL Zeus and GenQL provide comprehensive support and work with various technologies.

Okay so, this is a very short five minute lightning talk that I gave at a CIRCON. So I showed you GraphQL code generator and I assume that a good portion of people are familiar with it. It's a very popular tool, it's a great tool. So to kind of understand the importance of the impact of generated types with GraphQL and how important they are to making the experience enjoyable and better you kind of have to go back to the beginning.

So a long time ago in 2015 or 2016, that was the first time that I had ever tried to write GraphQL. And TypeScript also wasn't a very popular thing back then. If you look at the Stack Overflow Developer Survey in 2015, TypeScript wasn't even on the list, just wasn't present. And in 2021, now it's sitting at number two on the most loved list. So clearly a lot of things have changed. And so what did it look like back then if you wanted a type safe interaction between a GraphQL service and a consumer? So it's going to get a little bit Java-y. But basically you would manually have to define all of these types, which is silly, right? Because either you have a database type or you have like a Ruby on Rails or a C-Sharp or a type ORM model that already has all this stuff defined or it's in your GraphQL SDL. And so you would define manual typings for all of it. And then you fast forward a couple of years.

And in 2018, that's kind of critical mass, right? So things are starting to change. Facebook released their relay TypeScript compiler plugin, the first version in 2018. And GraphQL Code Gen popped up in October of 2017. And these tools are revolutionary. And I mean this is the beginning of just an unparalleled developer experience and the level of productivity was insane. So they enable schema-driven development. So what that means is that either your database types or your GraphQL schema can be the source of truth. And all the rest of the code and types in your application get generated and stay in sync with that. And so your consumer code is auto-generated just as a direct byproduct of your data model. And all of this code is type safe. And we saw this a little bit earlier, but essentially the way that it works is that you need to have a schema and you need to give it a specific, you need to give it specific operations. And the way that these tools have traditionally worked is that they, that's an attitude, is that they basically generate types just for those specific operations. So you need to write every query that you wanna use. I don't know how to erase that. Okay, well, that's just gonna stay there for a second. Okay. More stable annotations. Oh, hey, other people can write on the screen. Don't draw anything profane, but you can draw a smiley face if you want. Oh, I can clear it. Clear all drawings. Okay, if anybody wants to draw a little smileys on my screen, you can. Okay, cool. So what do we have today? There's been a recent set of libraries that sort of abuse the fact that TypeScript's type checking engine is at principle kind of a logic checker and a constraint solver. And these tools, they generate one TypeScript file and it contains all possible, I dig it, it contains all possible operations that dynamically calculate the return type queries. So we're gonna skip this boring bit, but essentially the way that this works is you see I have this like use type subscription here. And when I press autocomplete, it gives me all the options in my GraphQL API that I can use and they're all typed. And so instead of needing to write a specific query like user where blah, blah, blah, I can just, you can just fill these in dynamically and it'll calculate the return type. So you see here, we have user with only ID and number. If we put email in there, then now we have email and the return type. So it's pretty mind blowing. So, all right. Close the annotations. The tool that I personally use is called GraphQL Zeus for this. There's another one called GenQL. They're very similar and solid and they work with pretty much everything. So yeah, that's the intro.

8. Starting the App and Setting Up the Environment

Short description:

Let's reset everything and start from scratch. Remove existing Docker services. Open the project in a Dev container for a reproducible environment. Install PNPM globally and run PNPM install. Use the Vite launcher to start the V dev server on port 4000. Ensure the page is empty and toggle between light and dark mode.

And with that, let us kinda dig into the app. So, I'm gonna zoom this code in so that we can see stuff. And what I'm gonna do is just completely reset everything as if I'm starting from the beginning.

Okay, so, I'll move this chat. All right, so, we're gonna stop this. Boom, boom. And basically gonna do Docker compose down that be. Right now, what I'm gonna do is I'm gonna get rid of these existing Docker services that I had. So, I have Hasura, which is gonna be our GraphQL API and backend and I had a PostgreSQL database running. But I'm gonna wipe it so that we can all start from the same slate and kind of walk through things together.

Okay, so, with that done. I actually wanna show what this looks like when you open it just in case anyone is confused about the dev container thing. So, it basically looks like this. So, I'm gonna go Solve this directory and then I'm gonna go with insiders dot to open it here. To open it here. Okay. Okay. So, you'll get this pop-up, the folder contains a Dev container configuration file, re-open folder to develop and container. Then you're gonna press this re-open and container. And what that's going to do is pop you into a reproducible environment, that has like Node, all this other stuff set up. And there's also some recommended VS code extensions that when installed should give you a pretty decent working experience. So, the idea being you don't do anything, just clone it and click yes. And then when it asks if you wanna install the recommended extensions, click yes. Your setup is done. It's pretty cool, if you've never used Dev Containers, they're great.

Okay, so the first thing that we're gonna have to do is that this starter, vitez, I think it's pronounced by Anthony Fu, An-Fu. Super good. He uses PMPM. So I'm just gonna go with that architectural decision and when you boot it, it won't be installed. And so what you need to do is basically NPM install globally PNPM. Okay, and then after you've done that, then you do PNPM install. Which this is already up to date because I've done all this, but that's going to take a second. And there's this button down here. I'm going to close all these so you can see it open on this side. You'll notice this little V button down here. So this is just the convenience launcher, but it's pretty cool. If you click it, and say open in embedded browser. You run that and what that's going to do is that's going to start the V dev server for the project on port 4000. And it's going to open it in a embedded VS Code terminal, which this is going to fail because I manually killed the command, but under the hood, it's just running this command. Also, is this font size good for everyone? I can zoom in or out. Okay, sweet. All right, so we will leave the font. And you'll notice that if you click the Vite and you click open in embedded browser, it should launch this. You should have a tab over here called Vite. And it'll prompt you if you want to open it in your browser. The important thing is that under your ports list in the bottom which you can get, if you don't have this, you can click where these little icons of the X and the hazard sign are and then go to ports. And you should see a red dot on port 4000. Let's go ahead and reload this. And this should just be an empty page, sweet. And you can press this toggle button to toggle it light or dark.

9. Setting up SQL Database and Hasura

Short description:

We'll set up a SQL database and Hasura using Docker. Hasura connects to multiple databases, and we'll create a new table with some columns. After adding the table, we can browse and insert rows. The SQL tab allows us to run arbitrary SQL queries. This is how we create a database, table, and enter a record.

Hopefully that works for everyone and we'll check it in the regular browser as well. Okay, sweet. So we have an empty page. The next thing that we're gonna do is we're going to set up a SQL database and we're going to setup Hasura. Hasura. So if you haven't heard of Hasura, this is our website at hasura.io that explains it. And if you go here, hasura.graphqlengine, you can read more about this. So anyways, this is all open source for this demo. I've pre-packaged everything so that, yep, the commander on it locally. Yep, let's do that. So what we're gonna do is start a new terminal and it should run with Docker, compose up. And you probably want to pass dash dflag, and you should see it creating the Postgres and the GraphQL engine here. What that is doing is basically, we'll close this for now. What that is doing is pulling from this Docker compose and we have two services. So we're running Postgres version 14 from Docker and we're running Hasura from Docker as well. And we've mapped Hasura to local host 8060 on the port. And if we check here, you should get a prompt saying that your application on 8060 is now running. And the other way that you can check it is if we reload this, we should see our Docker container. So if you ever need to inspect what's going on here, you can right click this and inspect it. And we'd be able to get things like logs. So view logs here. And we can see what's happening inside the container. This isn't formatted, so it's hard to read. But yeah, so as soon as you've done docker-compose up-d here and confirmed that you do have two services running and the ports here are good, then we can go ahead and check that the console's actually up. So we'll go to the console, localhost 8060 and we're gonna zoom in a little bit. So there's a lot of stuff to cover here, but we're gonna kind of just skip to the data part and just focus on dealing with database stuff for now. So the way that Hasura works is you can connect multiple databases, so here we've configured it to connect to that same Postgres that's running in Docker but you can have more than one DB. So this is our default DB in our public schema, and if you wanna create a table, so we wanna create a new table, we can be like, you know, my new table and then we can say, okay, I want an ID. I want created at, I want updated at, I want, you know, some cool text and I want the type to be text and I want it to be unique. Okay. We'll skip some of this for now because that's not important. But if we just press Add Table here, then you should see that we have a new table listed under Public. And we can see our types here. We go to Browse Rows. We'll notice that we have no data in our database right now. We have no rows. We can come to Insert Row and be like, view is the best. And we just leave these as a default. And we save it. And you could see the kind of details in the payload here. And now if we come to Browse Rows you see we have data in our database. And to prove that this is kind of actually all like we've genuinely just created a database, created a database table and entered a record, we can do a select star from my new table, you'll see this little SQL tab on the left. This allows you to choose the database. In this case it's always just gonna be default because we only have one. And we can run arbitrary SQL. So we'll run that. And you can see that we do have this record. We could be like select, what do we call it? I've got some text. Some cool text. So there you go.

10. GraphQL API CRUD Operations

Short description:

We've created a full GraphQL CRUD API with real-time subscriptions. We can query and mutate data, and even apply filters. The API provides history of previous operations and supports subscriptions for instant data updates.

But that's not the cool part. The cool part is if we come back to this API page, you'll notice there's this graphical kinda like playground editor over here. It's easy to miss, you can expand the docs over here. These are clickable. So what we've just done is we have created a full GraphQL CRUD API. So we can do queries, mutations, and we even have real-time subscriptions on our data.

So if I say my new table, so we'll say a query, and I want the ID and the some cool text field, then we press run. You'll see that now we get the data from a database. So those are create. And we're going to delete this, and we need to add a mutation. So if you want to do this through the UI, go down here, and switch it to mutation. And then press add new. And that'll change these to be the mutation operators. We have two types of inserts. We can insert multiple, or insert one. So let's just do an insert one. And we're going to put some cool text is new thing. And the other thing that we want to put in is, that's pretty much it. And then we need to select fields. So let's just grab all of these. And so you can see it and we'll run it. So now we have a new record. So let's go back to our database. Let's look at our table. And we see that we have two records now. And if we come back and we click our history, we click history. We can see all the previous operations that we've run. We can just run the previous query that selects all of the MyNewTable records. And this time we'll get two. Pretty cool. But what if we want to filter it? So then we can just say, I want all of the records in MyNewTable where the ID is greater than or equal to two. And then now boom, we only get two. And we have these and, or, and not if you wanna combine multiple conditions. We have like date time operators, yada, yada. We also have, we could delete it, but let's do the exciting one. So fancy subscription. This is the part I always love to do. So if we subscribe to MyNewTable, and we basically select, the other thing is that you can always press Control Space in here if you wanna auto complete and kinda go up and down these. So we'll just grab kinda all of these. And we'll start that subscription. I close this documentation explorer, this down here. Okay, so we've started a subscription. It just looks basically the same as the query we just did. That's not impressive at all. But here's the neat thing. If we open data, and we pull this to the side, pull this to the side, let's close history. Let's close the explorer and pull these over here so you can see. Then what we can do is we're gonna insert a row manually into the database. So this will be third row. And when I save this, boom, instantaneous data updates.

11. Building a Meetup.com Clone with Hasura

Short description:

In a real-time UI, like displaying chat messages or meetups, GraphQL is useful. Azure's core basics don't require a new database. You can connect an existing database using the Docker command. Let's build a Meetup.com clone with simple models. Users can sign up for meetups and leave comments. There are two ways to get data: raw SQL or tools like P-SQL. Hasura is agnostic to managing migrations. Any questions before we move on?

So in a real-time UI, like if you're displaying chat messages, if you're displaying things like meetups or event listings, this is super useful. Yeah, so this is the kind of high-level gist of how the core basics of Azure work. It does not have to be a brand new database. You can come in here and say, let's close this. You can come in here and say, in default, manage database, connect database, and you can go ahead and select your database source, give it a name and then you can use, you can use the database URL, the connection parameters, the environment variable, yada, yada.

So the easiest way to try it if you have an existing database is just to literally run the Docker command and pass in the connection string to like a local test database and it'll generate all this stuff. So, I hope that was pretty cool. Those are the core fundamentals. It's not really what makes us so neat. The neat stuff is kind of in these other tabs, but we gotta go through the basics first.

Okay. So let's actually, let's actually build an application. So, kind of what I have here is, this schema diagram, and make this bigger. So, I felt like a semi-relevant application model would be to build something like a Meetup.com clone. And so, if we make the models really simplistic, what does that look like? Well, we probably have a meetup. That meetup has a location, name, description. It's gonna have a picture. And there's gonna be a date, a date time of when the meetup's gonna happen. And we're gonna have users. I've chosen email password, it could be user password. It doesn't matter. And what we're going to do is we're going to, we want to allow users to sign up to any meetup, though only one time per meetup. And we want users to be able to leave comments on meetups. The comments can be multiple. So if I'm John Doe, I can leave three comments on the View London meetup. But we're going to make sure that it's not spam. So hopefully that's like slightly less boring than a to-do app. I tried to balance keeping it simple versus keeping it interesting.

Okay, so to start, there's two ways that we can go about getting this data in there. And the way that you would choose is probably going to depend on how familiar you are with SQL and your preference for using tools. So this same little raw SQL that we used to run that query, that one-off query, we can also use this to do things like create the tables and track them like we did with the UI. So if you're a SQL wizard or you're just more comfortable writing things in text format, that's a great option to write your database models in your schema. And then you don't have to run them through the raw SQL. This is just a convenient way to run them. Obviously you could just connect directly to your database. Use like P-SQL or whatever the DB driver you have. You can also manage your migrations externally. So Hasura doesn't really have an opinion about this. We wanna remain agnostic. So if you're using like Ruby on Rails and you have database models in your schema and active record, or if you're using entity framework or Python and SQL alchemy or type O-M, whatever, that's fine. You can just continue to manage your database models and your migrations using like whatever tool. And then the only thing that you would manage is gonna be like some Hasura specific stuff that we'll find in a little bit and things like these permissions tabs and these other tabs.

Thanks Doosan. So yeah, hopefully that covers the basics. Before I move on, does anybody have any questions about like how any of this works or like functionality that they don't understand or just general questions, happy to answer.

QnA

Subscriptions and Permissions

Short description:

Subscriptions are observer patterns for databases, allowing clients to be notified and receive updated state. Hasura supports multiple databases, using Postgres' native notify functionality for pushing events to clients. It's lightweight and can handle tens of thousands to millions of live subscriptions. A benchmarking tool called GraphQL bench allows you to test subscriptions with low latency and resource consumption. There's a push for standardization with protocols like GraphQL over WebSockets. Hasura's GraphQL WebSocket package powers subscription functionality for various clients. Permissions for accessing certain rows of a table can be managed using the permission system and SQL schema.

All right. All right, it seems like we're good, subscription is so. Axel asks, subscription is basically an observer pattern for DB, yeah, that's exactly it. If you're, yeah, yeah.

Oh man, we got a, sweet, we got a bunch of questions. Awesome, I'm digging it. Let's do them all. So yeah, subscriptions are exactly like observer patterns for DBs. I don't wanna go into the gory details, but since we support multiple databases, the way that it works under the hood is a little bit different for each database. In Postgres, we use Postgres' native notify functionality when table events happen, and then we use that to basically push the events to the client. And it's super, super lightweight. You can handle tens of thousands, up to hundreds of thousands, or even a million live subscriptions at once, because of how lightweight they are. Though it depends on the payload. You can't send a gigantic 500 kilobyte payload across in a subscription, because there's no way to track the delta. It just resends the entire data every time there's an update, not just the difference, because then that would be very technically complicated. And so as long as you're not sending huge subscriptions, you can handle a pretty absurd amount of them. And I would say don't take my word for it. Myself and some other folks have put a lot of hard work into a benchmarking tool that basically wraps other, it wraps multiple other very popular load testing and benchmarking tools in a uniform interface. And it standardizes the results and allows you to... I'm getting too much in the weeds. If you go to this GraphQL bench, if you go to this GraphQL bench, if you go to this GraphQL bench repo, you can run benchmarks on subscriptions and you can see for yourself like how many tens of thousands of subscriptions that you can handle with like very low latency and resource consumption. And it's the same thing for, we have a neat little like visualization dashboard that can be built too. So you can like import your results and see like latencies response time, scatter plots, all this stuff. So yeah, and it has a TypeScript interface too. So if you want to run tests programmatically, you can do that. But anyways, yeah, sorry, I got sidetracked. It's like an, it's exactly like an observer pattern for the DB, when things get changed clients that clients get notified and they receive the updated state, okay.

While people subscriptions work over WebSocket implementations, or is there another? Yeah, so there's, that's a really good question. There's actually a big push for a standardization right now. So, this isn't part of the GraphQL spec itself, but there's a protocol called GraphQL over WebSockets and Hasura has a protocol called GraphQL transactions over WebSockets that allow you to wrap like multi, I won't get into that, but yeah, there's, if you're interested in learning more about this, you can check out this repo. And there is like a non-ratified standard that is considered a best practice. And I think the GraphQL foundation is working to get like put in the spec. So, and yeah, we'll actually see, we, this GraphQL WebSocket package gets used in the app and we'll see this in a second. It's the, it powers the subscription functionality for both Villas and a Oracle. And app, and I think that Apollo's client uses this under the hood as well.

How to take care of permissions. If an API client is only allowed to access certain rows of a table. Another great question. This was something that, yeah, yeah. So, all right, we're just gonna dig into the permission system right now for a second, I guess. Cause it seems like a couple of people have questions about it. This is something that I wasn't sure if we were gonna have time for, but I would love to cover it cause it's really important. So there's two questions. One is high level. How do you take care of permissions if an API client is only allowed to access certain rows of a table? Basically let's do this, I'm gonna go ahead and show you folks the next step of the tutorial where we kind of import this because we're gonna use the user database table to talk about permissions. So inside of the project, there is a file called schema.sql and like I said you do not have to do this to like write it manually this way. We could have just done it by clicking in the UI but sometimes I like to write the SQL by hand just because it helps me like think about it and like keep it all in my head at once. I can copy paste stuff. So if you take that content and you paste it in here, you folks are probably gonna need to also paste this create function. This got created when I made this table because I added the updated app column.

Tracking Tables and Foreign Key Relationships

Short description:

When connecting to a new data source or creating tables, the GraphQL API is not created by default. You need to track the tables to make them available for querying. Similarly, foreign key relationships need to be tracked for them to be exposed. Permissions can be set to ensure users can only see their own rows. Test data can be inserted using the seeds file.

So this is something we do under the hood for you. So I'm just gonna put that there. So, yeah. What I'm gonna do is, I'm gonna get rid of that. If you run DDL statements in this, you need to check the track this box. And if you hover over the little eye bubble, it'll tell you why. So I'll explain more in a second. It makes more sense when you see it.

Okay, so you basically, after we've created those tables, if we come back to public, you'll see there's these untracked foreign key relationships and it says that untracked tables or views are empty. Basically, what happens is that, I'm just going to create this table so you can see what it looks like when there's one there. And check track this. Okay, so that one didn't show up. So what happens is that when you first connect to a new data source, or if you create tables, it's not gonna create an API for them by default because that's a little bit sketchy to just expose all that, especially before you had a chance to think about permission rules. And so in order to create the GraphQL API and make it available to query, for a table, you need to press Track. So if I press Track here, you'll see it pop up on the left. And just to show you really quick, let's go explore. Currently, we can't query this. So what was that table called? It was like, untracked table, not tracked by default. Yeah, it just doesn't show up at all. Okay, so if I track it and I go back to my API, then I can now query on this field and it has the correct stuff. Okay, now, untracked foreign key relationships. So we see in the schema diagram that, we see that user, that like meetup has a meetup users and meetup comments, but if I go to my API, I can't query that. So if I go to query and I asked for a meetup, there's no meetup users in here. I can't get to my relationships. And so the reason why is because the foreign keys haven't been tracked. So if I go ahead and track this foreign key from meetup user to meetup id, which let's just press track all, then now you'll see in the relationships tab that it's added these relationships. So now we have an array relationship to meetup comments and meetup users. So if I go back to the API on meetup and I look now, then I can dig down into all the users that are signed up for the meetup. I can get the users, I can get to the user, I can get the users to meetup. I can get to the user, I can get the user's email. We can go here, we can grab meetup comments, text, stuff like this. So you need to track those and you need to track the foreign key relationships in order for those to be exposed.

Okay, so back to the permissions question. And I'm sorry, I'm going to try to get through as many of these as I can. These are really good questions. What if we want to say, here's a super common scenario, users should only be able to see their own rows. We don't want a user to be able to query our users table and just see all of our other users' personal information. So there's another folder, another file in here called seeds, which just has some test data. So you could also again, add this through insert row manually. This is just a little bit faster. So we're gonna insert users. We're gonna insert three users. We're gonna insert two meetups, one in London, one in Miami. We're gonna sign some people up for the meetups. So basically, users, one, two and three are gonna go to Vue.js London. And then user two is gonna go to this Miami beach thing. And we're gonna put some comments on there. So if I run that, now we come back, we can see that there's data and all these tables.

Okay, so this is what I'm gonna do. First thing you need to do is you need to make a role.

Configuring User Role Permissions

Short description:

We'll create a new role called user and allow them to select rows without any checks. However, this exposes sensitive information like passwords. To fix this, we need to add a check to the user role permissions. By checking the ID against the accessory user ID, we can ensure that only the authorized user can access the data.

So we'll say that there's a role called user. And what we're gonna do is we're gonna say that user can just select with no checks. So we're in the user table under permissions. Put user in the role to make a new role and then click select. Then we're gonna say allow user to select rows with no checks. They can just select all of them. Also no limit. And let's give them toggle all column permissions and we'll save that.

Okay, so now I got a checkbox here. Let's go back to our API. So, and here's the problem. So if we ask for user, ID, email, and then let's get some something juicy. Let's get the password, right? Probably don't want that hanging out there. I'm gonna say that I am a user. So we need to check this box that says, give us a role. And the role that we put in the value. These are HTTP headers, by the way, for our request. The role that we put here is gonna map to the role that we put in the table. So permissions, this is the role we wanna use. So we say, hey, Hasura, for this request, I'd like to be a user. You can't do this. You can't just ask to be an admin. There's rules to this, but I've unlocked this application so that we can, for demo purposes. If you read our auth docs, it explains more about how this works. But just bear with me here.

And then what I'm gonna do is I'm gonna say that I'm gonna give another value in my header, and I'm gonna give AccessHera a user ID. And let's say that I'm AccessHera user ID one. Now this role and this user ID are set by your backend. So when you log people in, you basically sign a JWT, and you say this is the role that they are. This is the roles they're allowed to be if they want to put a different role. And these are all the custom claims. So you can put anything here. You could put like AccessHera organization ID, and then like AccessHera user ID if you have a multi-tenant app, right? So you can sign whatever you want on your backend, and you know that it's been validated. But anyways.

So this app, it's all just unlocked, which means that we can kind of play around with this. So I'm going to make a request and I'm going to tell a Hesera that I am a user role and that I am user one. So I'm going to make that fetch request, and this is what happens. I see everybody's password. Not good. Really, really not good. So how do we fix that? It's pretty easy. So you come to your role and your table. So we're in user permissions and the user role. And you say, when a user role tries to select a row, there needs to be a check. And I want you to check that the ID is equal to the accessory user ID. I think I have broken this. Save that. Permissions updated. Select. I have broken that.

Handling Permissions and API Security

Short description:

When handling permissions, you can use either Hasura roles or manage roles through database tables. Hasura roles allow for more complex permission setups, while using database tables provides a catch-all single role. To make the API secure, an admin secret and unauthorized role should be added. Additionally, a JWT secret is required for authentication. These requirements ensure proper authorization and security.

One second, I'll manually fix it. Okay. All right. Okay, so I don't know why that happened. Basically what we're saying is when a user tries to select this, we want to make sure that the ID is equal to the current user ID that's been signed in our token. And this is gonna be the ID of the row. So this is user.id. And so now what happens with query hopefully is boom. Now we're user one, we can only see user one. If I sign a new token, so let's say I have a Node.js backend. I sign a new JWT and the claims I put X to user ID two. I run that and you'll see that I'm user ID two, user ID three, user ID four, nobody. So that is a very, very high level example of how permissions work. You can do super complicated things with them using Boolean and, or not and exists, which lets you select across table and schema. So the other way we could have said this is like, if there exists an table user, where ID is equal to blah, blah, blah, blah, and we have a bunch of articles on this, but yeah, that's the general gist of how you do permission stuff. To make sure. And then the other permissions question is that somebody says that they have, users can have multiple roles and multiple permissions can be attached to each role. So the other way that you can do it is instead, I'm gonna put this, I'm gonna put this chat in like a notepad so that people can see it. This is the question. The other approach to this is instead of using Hasura roles, you can use database tables. So basically, you can do something like create a table and just be like admin user and we'll just be like generate by default primary key. We'll just put like user ID and foreign keys, add a foreign key from user ID, ID, user ID, hit save. Add a table. So the other way that you can do roles is by doing it in the database. So, if we insert some rows and we say that user with ID two is an admin user, we can go into meetup and we can basically say permissions and we can say basically only allow somebody to look at a meetup, right? This is a terrible example, but it should just be any arbitrary table, right? When the, basically, so if the, if the, oh man, I'm blanking. If there exists in table admin user where ID equals, yeah, that's wrong. So you basically write this, you basically say that, somebody with the role user can select from this table if the current sign-in users ID is present in the admins table. So instead of using a bunch of like Hasura roles, so like role one, role two, role three, you can use just a catch all single role, like just user versus anonymous which is like not signed in or authorized at all. And you can manage your roles through database records. And you would of course, make sure that like the only person that can write to the admin users table would be the actual owner of the Hasura app. So there's, that was a little bit more involved than I maybe wanted to go on this session. But yeah, there's two strategies. You can either use Hasura roles or you can use roles by setting up database tables that have values that you use to look up to see what permissions are allowed. Like kind of like an ACL list. And we have some blog posts on this. I hope that answered your question. Make request, request.

Okay so, the person whose first name I can't pronounce and last name is spelled Peter, is asking about making these requests with headers and is worried about the data being sensitive. And they're like, can I just put it in like the password or whatever in here? No, absolutely not. So the reason why I'm even able to do this and just like take a role and say that I want to be a user and I want to be an admin is because if you look in the Docker compose file, the instance hasn't been configured for authorization and security. It's basically like a test instance that's fully opened. So if we wanted to actually make it secure, what you would need to do is you need to add an admin secret, which is a password that makes it so that is required to log into that web console or to interact with the APIs at all. The other thing that you would have to do is add a SerigraphQL, I believe it's called, it's unauthorized role. And this is the role that people get assigned if they're not logged in as anybody. So you would say like, okay, your role is anonymous. Okay, that's the second requirement. The third requirement is that you need to set a JWT secret, so you need to know which if you're logged in, but you need to know why. And then there's all other requirements that you get submitted throughout. So you can have a secret or not. There's no, like conditions that require a JWT or there, so we don't know that unless you get that requirement everywhere, and that's something that privacy is, just like even for me, there's a little bit more logic in doing.

Integrating Authentication and Authorization

Short description:

To add authentication, you need to provide the master password and a JWT (HS256 or RS512). Additionally, an unauthorized role is required. Integrating authentication involves creating a handler for login and sign up. In our e-commerce application, we have implemented authentication using GraphQL queries to generate a JWT securely. The implementation is about 120 lines of code. For more details, you can refer to the login and sign up files in the API actions folder.

So there's also a requirement for borders. This is what you would need to actually add to any sort of like security or ability to log in at all. You need to give it the master password to log in. You need to give it a JWT that can either be HS256 or it can be an RS, I think it's RS512, which is that huge gigantic key. And then you need to give it an unauthorized role. And then if we were to do Docker compose up, I guess I could just show this right now. Basically what would happen is that I'll show the app working first and then maybe in a second, I'll show what happens if we do this. The app will break entirely because we'll have no access to make requests because we're not logged in and the auth isn't integrated. But to answer your question, those are the first steps you would take to integrate the ability to add auth. And then you just need something, you just need like a little handler that can handle like log in and sign up. Which is very small. So we have this like e-commerce application which is like a totally not Amazon clone that we built that has like auth and all this stuff in it just to kind of show like a more real world app. And if you look in here, inside of pages, API, actions, there's log in and sign up. So if you look at this file, so to log in is basically just to like query per user where their email is equal to the specific email and then to generate a JWT. And this is where we like securely sign the user ID. And we say that the only the default role is user, the allowed role is user. And so it's like, it's like 120 lines to write your own JWT off for this. And same thing for like sign up. This isn't something that we had the time for today. But if you're interested you can look at this for a reference implementation of like your own JWT off. Just using Bcrypt and stuff like that. Yeah, yeah, yeah, we get the B part.

Application Setup and Library Integration

Short description:

This part introduces the setup of the application, including the integration of common libraries for using GraphQL with Vue. It covers the main.ts page, which includes Vite, Vue 3, Pina, VueX, and Apollo Client. The Shared GraphQL WebSocket Client and Ercol are also mentioned. The goal is to show how these libraries are used in practice and discuss state management.

Okay, so. Basically, the way that this application has been set up is that I've sort of integrated most common libraries for using GraphQL from Vue. And so, we can kind of skip through all of this because this doesn't matter, but in the main.ts page, what you'll find is a Vite and Vue 3. It has a Pina and a VueX store registration. It has Apollo Client that handles HTTP and WebSocket connections, both queries and subscriptions. This is the Shared GraphQL WebSocket Client. I hope I'm pronouncing it right, VILS. We have Ercol hooked up as well. We've just kitchen-synced the whole thing in there. And what I wanted to show is what is using these look like in practice. Then you can judge for yourself, maybe what the trade-offs are. We can also talk a little bit about state management.

Implementing Fetch and urql

Short description:

The fetch page in the index shows user emails, which are retrieved using a GraphQL request. The request is a post request with a JSON body containing a query key. The table dynamically generates rows based on the input object. Subscriptions cannot be implemented using fetch as it is for HTTP, while subscriptions require WebSockets. urql, which uses GraphQL code gen, allows you to write queries inside tags and auto-generates types. Typed Document Nodes ensure type safety and catch errors if properties are added or removed.

And so if you go under pages, this is an empty index page. The idea was to fill this in with meetups that we would leave comments with. I can try to rapid fire go through these and do the actual implementation if that sounds good.

So let's start with fetch because this is fundamental to understanding it. So what is a GraphQL request? So if I open my embedded browser and I go to localhost 4000 slash fetch. Okay. So these are page based routing using a V plugin, so if we look at this page, what we see is this table that just shows us the user emails and we see it's fetch page. So to understand GraphQL, basically the only thing that's happening is that we're sending a post request, we're sending a, a JSON body that has a query key. So here we're asking for a user, we're asking for ID and email, uh, and then that's pretty much it. Uh, so yeah, I mean the rest of this is just sort of handling like fetch state, which you probably ought to use suspense and handle that bubbling off in a wrapper component, but it is what it is. And then, yeah, we're just displaying this table, which just shows the data and kind of all this does is just dynamically generate rows based on the input object. So if I change this selection.

How would you implement subscription using fetch? You cannot implement subscription using fetch. That's why you need a WebSocket client. Because fetch is HTTP and subscriptions are WebSockets. So there are both in this app. And we'll cover them. You write your GraphQL queries straight in and you just go through and you create your query. And then you only have ID now and we don't have user in our table. So it's just super easy. Boom. Super, super easy. So, yeah. And then unmounted I'm just calling fetch. All right. So, let's pop over to the next one. Let's maybe look at urql. So, this is using GraphQL code gen. We don't really have time to cover it as much as I would like. But the way that it works is that you sort of write queries inside of these tags. And it will auto generate the types. And so, the result of that is that if we hover this, you can see it's this typed document node. And it returns this all users subscription subscription. These type document nodes are one of the newer things. They're largely due to a single person from the Guild as far as I know. It's really cool. They work with most tools. So, here's the cool thing about Typed Document Nodes. We have this use subscription from Urql view. And I pass in the all users query. Then what happens is that the type of my data matches the response type of the query. So, if I go ahead and do data.value.user, you can see that it's an array of this user object. So, super cool, and it's all typed. So, if we were to add or remove properties here, they would get reflected in the generated type which you can kind of see how that works here. We'll skip over that. The reason why that is cool because if I do something like this, basically if I were to do something like data.user.createdAt it'll say, hey, that doesn't exist on your response type. And so, you can immediately catch errors which is super cool. You'll just, they'll be red everywhere that you've broken if you update your API or you write the wrong thing.

Handling Reactive Queries and VLS Implementation

Short description:

You can catch errors immediately, and the syntax for subscriptions is similar. The Url page demonstrates a subscription in action. The VLS implementation and Apollo are also discussed. Urkel and Villas have similar APIs, with Villas being view tailored and lightweight. Both libraries can handle reactive queries, automatically rerunning queries when values change.

And so, you can immediately catch errors which is super cool. You'll just, they'll be red everywhere that you've broken if you update your API or you write the wrong thing. So yeah, and we'll go ahead and go to the Url page. This is using a subscription. The syntax is largely the same. It's been really hit or miss with this like embedded browser thing. I love it when it works.

Okay, sweet. So yeah, this is the Url page, we've got this stuff. Again, we can kind of take away the prompts, save it. It should just auto update. Oh, it's because I broke the... I don't have the code gen running in the background. You need to continually run this code generator that watches for changes and then regenerates TypeScript types when you use this. But I'm going to fix that, put it back, and then what we'll do is we'll show a subscription working. Okay, so we'll pull that open... 4,000. We'll go to Urkel. Okay, this is our users. And then we'll go to user. Let's pull this over here. Man, I hate Windows. Pull this over here. And let's go ahead and insert a row. The insert can be either directly through the DB, or we could insert through the GraphQL API. Either way, it'll get picked up, which is cool, because it means that your subscriptions will pick up things from automated cron jobs that might be inserting data in batches every night or whatnot. So, if we save this, then boom, immediately it updates. So, okay. So, let's continue on.

And we will move right along to the VLS implementation, which I hope I'm pronouncing that right. Probably not. Which if I just kind of swap back and forth between these, you'll notice that they're basically the same. And also, Apollo is basically the same. We'll get to this in a second. I know a lot of people are uh into Apollo, but there's a lot more content available for Apollo stuff than there is for tools like, you know, Villas. But anyways, so same thing, we'll go to Villas. Which maybe I've broken somehow. Oh no I didn't, it was just super slow. Yeah so basically exact same thing, very similar API, though view tailored and lightweight. I really like it, I think Urkel and Villas are both fantastic. One thing that we don't really have a lot of time to cover super in depth is that both Urkel and Villas can handle things like reactive queries. So let's say that we had a computed data, so if we had, so let's say we had const users. And this was a list of users. Let's do this kind of from a query, and let's say we had const age filter equals 18. What you can do is basically make it computed. You can make a computed value. That reruns your queries automatically, which is super cool. Yeah, so this is something I wanted to point out that's really cool. So, you have an ID, right? You can put your query inside of your query string inside of view computed, and then you can use that inside of your query. And what'll happen is that if you use like a Vmodel or you change the value, the query runs automatically, which makes this like trans.

Working with GraphQL APIs and State Management

Short description:

Urkel and GraphQL Zeus are powerful tools for working with GraphQL APIs. Urkel allows for transparent JSON data syncing with reactive views, while GraphQL Zeus generates a single SDK that infers return types based on selected data. The syntax for using GraphQL Zeus is intuitive, with auto-completion and type safety. It provides a comprehensive auto-complete feature for your entire GraphQL API. Highly recommended for its ease of use and type safety. Apollo integration is also shown, with examples using GraphQL Code Gen's type document node and the view Apollo composition API. The choice between using the GraphQL client for state management or traditional stores like Vuex or Pena is discussed.

It's almost like your API data is just this like transparent JSON that's local and it's in sync with your like reactive view refs and state, which is super, super cool. And, yeah, Urkel can do this as well. I don't know that Apollo can do it. I don't wanna make a statement either way because I could be wrong. But yeah, you can do some really neat stuff with this.

Let's go ahead and look at the last two ones. And so, this one's a little bit different. So this is using GraphQL Zeus from my presentation. And so the reason why I prefer this is that instead of writing individual queries and then generating types for specific operations, what this does is generates one gigantic SDK that does a bunch of TypeScript magic to automatically infer the return type based on what you select. So you can see that the type of useAllUsers query is users with ID and email, which is a number in string. If I get rid of email, then it's just number. And so the syntax for this is, we could just do it from scratch. Basically, the way that it works, let's get rid of this. We press Control-Space here to auto-complete, and then, boom, it's every single operation in your entire GraphQL API, and they're all typed. So let's say we wanna get meetups. So we start with meetup, and then, it's an array. The first object is our query arguments. So what are our arguments? We can do where, order by, offset, limit, distinct on. So meetups, where, name, iLike, percent, view. Okay, so that would find every meetup where the name is case insensitive, like view, and then the second thing that we need to pass is our selection. So what do we want from the meetup record? Alright, I want, give me an ID, give me the name, give me the location, the date time, and then let's dig deeper. So I want to know all the users who's coming to my meetup. And so then again, we get to filter and I want only meetup users where the, where the user email equals admin at site.com. And then I select again and I want their, the users ID and email, that's what I'm calling. So this is a little bit ugly, but if we check the return type, it's automatically typed. And so it's like if you had a magic auto complete that was just your entire GraphQL API that spanned multiple databases, multiple REST, multiple GraphQL services and it was completely type safe. So yeah, this is my preference, GraphQL, Zeus, or GenQL. So you have gql.query and then there's also mutations where we can mutate data and we can also do subscriptions. Again, with that same sort of syntax. So highly recommend it, that's really how we came up with the term. Thanks, Allen, bye. I hope you have a great day. Thank you for hanging out. Then we're one minute over time. Finally, I'm just gonna show the Apollo integration. Okay, so this is basically using two ways. The first is with GraphQL Code Gens type document node. It looks really similar, so it's this use subscription. Again, we have like typed data. And then the second example, which uses their view Apollo composition API. So this generates special operations. So you see, they're all typed here, you can come here. This is all generated and typed. And yeah, the usage is pretty similar. This one's a little bit shorter because it's generated per operation, but they're roughly the same. And then again, it's kind of the same stuff here. We didn't get to cover Pena versus Vuex stuff. I'm gonna give a 30-second recap of it if that's all right. Here's the problem, the conundrum with GraphQL, like state management and using GraphQL and applications. You have a choice between letting your GraphQL client manage your application state or using a traditional application store like Vuex or Pena and just using the GraphQL client to fetch data, which you can then store it in your store model.

Choosing Between Apollo, Villus, and URQL

Short description:

Apollo encourages using it as the entire application state, while Villus and URQL focus solely on data fetching. Personally, I prefer using Vuex or Pina for state management and storing critical information in a global state. Apollo offers caching strategies for optimal efficiency but introduces complexity and potential caching issues. Using Pina or Vuex for state management and GraphQL for data fetching is conceptually simpler but may sacrifice some optimization opportunities.

So Apollo encourages you to use Apollo as your entire application state. So you pull data from the server, but then what you do is you write a local, a sort of local GraphQL schema and local GraphQL resolvers, and you write like... You write like a local GraphQL schema that models your store state, and you mix that in and manage that with your application. With Villus and with URQL, there's no state management, they just do data fetching. And the idea is that you're free to manage the state how you wish. So, it's up to you.

Personally, I prefer to use something like Vuex or Pina and just use GraphQL inside of individual components and co-locate the data that needs fetching, and what I do is I just store certain bits of information inside of a global state. So, things like a user's refresh token and stuff like that. Yeah, so Daniel says, I use Vuex ORM and I've written a recursive function to take the response and put it into the entity's front-end database. Yeah, keeping something like a front-end database. Vuex ORM looks super cool. You see people very split on the issue. I think they both have pros and cons.

So, the pro of using Apollo is that, in theory, it should be more optimally efficient because it can handle, its caching strategies can be used across like your network and your local store. Subjectively, I think it introduces a lot of complexity. And, I personally have, time and time again, seen people like run like banging their head against the wall because they're running into caching issues or forgetting about caching. And, caching is a difficult thing to get. It's just a difficult thing to get right by itself, kind of let alone when you mix it with your regular non-networked application state. So, the trade-off is if you're using something like Pina or Vuex, VuexORM to store your critical info and using GraphQL as like a data fetching. I believe it's conceptually simpler and easier to follow. But, you may be losing out on some like optimization opportunities. So, it's a nuanced argument and do what you want. But, make your own decision. And, I just wanted to bring that up. That was the last thing I had.

Watch more workshops on topic

GraphQL Galaxy 2021GraphQL Galaxy 2021
140 min
Build with SvelteKit and GraphQL
Top Content
Featured WorkshopFree
Have you ever thought about building something that doesn't require a lot of boilerplate with a tiny bundle size? In this workshop, Scott Spence will go from hello world to covering routing and using endpoints in SvelteKit. You'll set up a backend GraphQL API then use GraphQL queries with SvelteKit to display the GraphQL API data. You'll build a fast secure project that uses SvelteKit's features, then deploy it as a fully static site. This course is for the Svelte curious who haven't had extensive experience with SvelteKit and want a deeper understanding of how to use it in practical applications.

Table of contents:
- Kick-off and Svelte introduction
- Initialise frontend project
- Tour of the SvelteKit skeleton project
- Configure backend project
- Query Data with GraphQL
- Fetching data to the frontend with GraphQL
- Styling
- Svelte directives
- Routing in SvelteKit
- Endpoints in SvelteKit
- Deploying to Netlify
- Navigation
- Mutations in GraphCMS
- Sending GraphQL Mutations via SvelteKit
- Q&A
Vue.js London Live 2021Vue.js London Live 2021
169 min
Vue3: Modern Frontend App Development
Top Content
Featured WorkshopFree
The Vue3 has been released in mid-2020. Besides many improvements and optimizations, the main feature of Vue3 brings is the Composition API – a new way to write and reuse reactive code. Let's learn more about how to use Composition API efficiently.

Besides core Vue3 features we'll explain examples of how to use popular libraries with Vue3.

Table of contents:
- Introduction to Vue3
- Composition API
- Core libraries
- Vue3 ecosystem

Prerequisites:
IDE of choice (Inellij or VSC) installed
Nodejs + NPM
JSNation 2023JSNation 2023
174 min
Developing Dynamic Blogs with SvelteKit & Storyblok: A Hands-on Workshop
Featured WorkshopFree
This SvelteKit workshop explores the integration of 3rd party services, such as Storyblok, in a SvelteKit project. Participants will learn how to create a SvelteKit project, leverage Svelte components, and connect to external APIs. The workshop covers important concepts including SSR, CSR, static site generation, and deploying the application using adapters. By the end of the workshop, attendees will have a solid understanding of building SvelteKit applications with API integrations and be prepared for deployment.
React Advanced Conference 2022React Advanced Conference 2022
95 min
End-To-End Type Safety with React, GraphQL & Prisma
Featured WorkshopFree
In this workshop, you will get a first-hand look at what end-to-end type safety is and why it is important. To accomplish this, you’ll be building a GraphQL API using modern, relevant tools which will be consumed by a React client.
Prerequisites: - Node.js installed on your machine (12.2.X / 14.X)- It is recommended (but not required) to use VS Code for the practical tasks- An IDE installed (VSCode recommended)- (Good to have)*A basic understanding of Node.js, React, and TypeScript
GraphQL Galaxy 2022GraphQL Galaxy 2022
112 min
GraphQL for React Developers
Featured Workshop
There are many advantages to using GraphQL as a datasource for frontend development, compared to REST APIs. We developers in example need to write a lot of imperative code to retrieve data to display in our applications and handle state. With GraphQL you cannot only decrease the amount of code needed around data fetching and state-management you'll also get increased flexibility, better performance and most of all an improved developer experience. In this workshop you'll learn how GraphQL can improve your work as a frontend developer and how to handle GraphQL in your frontend React application.
React Summit 2022React Summit 2022
173 min
Build a Headless WordPress App with Next.js and WPGraphQL
Top Content
WorkshopFree
In this workshop, you’ll learn how to build a Next.js app that uses Apollo Client to fetch data from a headless WordPress backend and use it to render the pages of your app. You’ll learn when you should consider a headless WordPress architecture, how to turn a WordPress backend into a GraphQL server, how to compose queries using the GraphiQL IDE, how to colocate GraphQL fragments with your components, and more.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Vue.js London Live 2021Vue.js London Live 2021
34 min
Everything Beyond State Management in Stores with Pinia
Top Content
When we think about Vuex, Pinia, or stores in general we often think about state management and the Flux patterns but not only do stores not always follow the Flux pattern, there is so much more about stores that make them worth using! Plugins, Devtools, server-side rendering, TypeScript integrations... Let's dive into everything beyond state management with Pinia with practical examples about plugins and Devtools to get the most out of your stores.
Vue.js London Live 2021Vue.js London Live 2021
20 min
One Year Into Vue 3
Top Content
Vue 3 may still sound new to many users, but it's actually been released for over a year already. How did Vue 3 evolve during this period? Why did it take so long for the ecosystem to catch up? What did we learn from this process? What's coming next? We will discuss these questions in this talk!
Vue.js London Live 2021Vue.js London Live 2021
8 min
Utilising Rust from Vue with WebAssembly
Top Content
Rust is a new language for writing high-performance code, that can be compiled to WebAssembly, and run within the browser. In this talk you will be taken through how you can integrate Rust, within a Vue application, in a way that's painless and easy. With examples on how to interact with Rust from JavaScript, and some of the gotchas to be aware of.
Remix Conf Europe 2022Remix Conf Europe 2022
37 min
Full Stack Components
Top Content
Remix is a web framework that gives you the simple mental model of a Multi-Page App (MPA) but the power and capabilities of a Single-Page App (SPA). One of the big challenges of SPAs is network management resulting in a great deal of indirection and buggy code. This is especially noticeable in application state which Remix completely eliminates, but it's also an issue in individual components that communicate with a single-purpose backend endpoint (like a combobox search for example).
In this talk, Kent will demonstrate how Remix enables you to build complex UI components that are connected to a backend in the simplest and most powerful way you've ever seen. Leaving you time to chill with your family or whatever else you do for fun.