GraphQL - From Zero to Hero in 3 hours

Workshop from:
React Summit
React Summit 2022
Bookmark

How to build a fullstack GraphQL application (Postgres + NestJs + React) in the shortest time possible.


All beginnings are hard. Even harder than choosing the technology is often developing a suitable architecture. Especially when it comes to GraphQL.


In this workshop, you will get a variety of best practices that you would normally have to work through over a number of projects - all in just three hours.


If you've always wanted to participate in a hackathon to get something up and running in the shortest amount of time - then take an active part in this workshop, and participate in the thought processes of the trainer.



Transcription


so My name is pavazzaretsky. I'm it's already mentioned here located in Berlin. I live. hosting all my life here in Germany I'm working as a concert right as a consultant and also as a trainer. I have a long career and software development. I started as a traditional job Enterprise of engineer. I quickly I we realized it's okay. It's nothing really for me. I preferred work as full stick developer on on different distributed systems for example, and later on I decided to move on into the space of mobile applications and font in applications. I do it for a while maybe for a couple of years and now maybe four or five years intensively in different projects. I started But some very large Enterprise applications here in Germany in it systems or mutton fire. For example, when when I realized okay, I really I really enjoy this with small culture, right? There's a small culture of developers where the developers Drive the ideas Drive the Technologies. So I prefer to work and startups Although I've seen quite often the same stack. All right, just quite often in the background some Java codes and spring codes and performance fonted obviously JavaScript and so on and so on. Usually it's the same Technologies. It's Unique how the teams work with this Technologies. All right. It's very unique and I struggled a little bit to finding the right path of how to do things with this Technologies. Therefore I think a good approach. To to start is actually is to do some workshops right to do some workshops very soon, maybe with an advanced lecturer or maybe with someone who is already into this technology and shows someone the way to go and that's exactly what we'd like to do today. I've written a lot of applications with next Jazz a lot of application with no jazz in the backend. For example, a lot of applications with graphql is an API. and the most knowledge This is something I'd like to share with you. Also some patterns some design patterns on some good practices. I wouldn't say it's their way to go on you and you have to do things exactly like I show it obviously there are a lot of ways to do the same things. It's just one approach. It's my Approach which already Works in a lot of applications. So what do we want to do today here together? I decided instead of having some presentation for you or something very. Yeah, so some Fury. Let's do some hardcode coding. All right, some some coding like a hackathon. Let's decide. What can we do in such and maybe three hours maybe in two hours. Is it even possible to get an applications up and running in such short period of time So what we'd like to do today is a small social applications named Michael Events where everyone can over participants of a users of this application can create so-called Library events, you know it maybe the idea of meetups rights meetups are very well prepared. Yeah, that's why Name something so guess meetups, but Micro events are very spontaneous events created to maybe maybe right now. And users which are interested into this event can join this event and leave it. For example, let's pay basically that's it. And where from from the technical perspective we'd like to use prosperous as persistent storage. So the traditional and database it also would like to use Nest shares of a microservices actually for the API behind it. Right. We'd like to use type 1. as an object relational method and we'd like to use graphql. Right graphql to expose our API to the public world. On the frontend signs. We'd like to use next.js with typescript. Right. So with that typescript template because I think it's the way to go today to give statically type sales right to to avoid many errors on the runtime, which can be avoided because we already will 100. So I propose here to work together on this application. You can use this report as a starting point. Let's go through this report very quickly. basically That's it. We have a postgres setup. You have an API which is basically even sjs application and we have a web application web application is next based application. When you check this Repository. Or if you clone it on your local system, right you can see. The View maybe like this right we have this readme this code workspace actually it's five for your Visual Studio code which creates a workspace with this free projects within it. So let's open it together. right You do it so clone this application first start code, which is the code and open. this workspace Here it is. So wait a moment. I said let's create an application completely right from the beginning and we are using a starting point as the typical seed applications. Yeah, that's true. The reason for it so I already made make some experiments with this workshop and with this setup and basically it's quite easy. It's quite easy to show right but it's a barrel very time consuming. right, and sometimes we have maybe Let's say some minor errors inside it or we overlooked something and we spent a lot of time just to fix this one one little thing. So basically, it's a very real simple setup. Let's go through it, you know in a moment, but we'd like to use it as a starting point for our application. Whenever you have questions. Please ask. Just unmute right and ask them directly. If you like to follow please clone this GitHub repo. The code together with me. Maybe you haven't different approach when I when I have and please share it with us. right so what do we have here when we start this application when we start with workspace? As you can see we have three projects inside it web API and docker. The first thing is the docker setup. Basically, it's just prosperous. Alright basically just postgres with it initial user micro events with an initial password and the database. Right, if you already have postpres running an instance, right? It's not necessary to have this to have this to use the stalker set up here. Just make notes on the user and the password and the database you already using. In such in this case scope, please do API project. to the app module TS and here you see the setup for your postgres. So basically it's for you username the password in the database. Right just make it up and running. This post was instance and make sure that it matches the configuration here in the app module TS. so how to set up actually all of this Right. We don't really go through this. It's very well documented on the sjs web page and it's very well documented on the next Jazz page to how to create an initial setup. Let's just go through a couple of things which are crucial for this graphql setup and this type of setup here. first of all You always necessary links, right? So go to the graphcare page. You see what you usually have to do in order to enable graphql in your nest JS application. Just just graphql out of Industries the namespace it's Apollo because we're using Apollo server Underwood. We're using graphql space model and we using the Apollo server x-ray Express that bindings right because of our in our case. We're gonna go by default with this Express middleware for next year instead of testify. For example Basically, that's it. Some minor thing still to do if you go to your API application. Again to the app module. Here we are. Make sure you have draft you have enabled here for roots, right? Using the Apollo driver and we like to have this. schema file auto-generated for us as you make my toots or not necess allows us to work in two modes with graphql. The first mode is called first. The second one is schema first. You we decided to have a code as a single source of Truth. So we don't really write the schema on ourselves instead of it. We design it to get the code the typescript code. B model we'd like to expose as a graph API Okay, what's necessary to do for type 1 that's the second link? in this Discord Channel hearing Here we go. Right. So basically that's the type and integration. We have to install next year's type 1 type home, obviously Right and then we decide what's our driver. What's what's our persistent storage? What's on my relation the database system behind it. We're not going with my sequel instead of it with going with possibly. So we have to use PG here instead of my SQL. Here it's exactly the same setup as we see here in our application. code base All right. So here we go. You're going with postgres local laws on the default ports and they've already mentions setup. Instead of deciding. Okay, and we'd like to Put into this area or the entities we're creating. Now one by one we decided to how to look up for them based on the naming of a fire. And so we decided okay. Let's look for entities. Let's look for our relations. In our code base. I have a Time Spirit or JavaScript. Actually, this JavaScript doesn't really matter because we have new typescript only invest setup and that's enough. Another package. I already installed here is this snake naming strategies out of this time on game strategies package. So what is this? So what as you already know type all? This and object relational method. This means we writing typescript classes and like to map them to tables on our databases. management system But how to do it in terms of naming? Chemical case or uppercase lowercase snake case what's impossible? So a traditional approach to do it in prosperous is to go with this snake naming strategy. So when you have something like fuba written chemical case and your types of codes, it becomes in lowercase. Let us full minus bar as a table name, right? That's exactly what this game X strategy does. we also have a set which allows us to develop our application quickly right and nice with a nice developer experience. So with synchronizing and it's directly and we're dropping with schema every time we restarting the application. And so for tempted from time to time, it might be important for because things goes wrong when we develop so we decide maybe to kill our application to kill our API and we started and have hopefully an initial clean setup in the database. Right. So that's the drop schema actually when a property here this case. so that's it here in and in the API one thing I forgot to mention is how to work actually in this Visual Studio code how to make things easy for us and good approaches to open a couple of terminals for us. Let me do it. right forward beginning For example when I start with the API here. right I go maybe to the web application. And I decide to open. Right, I decide to open the back terminal for the API application. Let's rename. Those two terminals. So first one is the web application. The second one is the API. So why do we have this API as a debug terminal and the web application isn't and let's say traditional term. Right because the back term then allows us to start the scripts running here out of this terminal. In the back mode. So actually we connected our IDE to our one runtime. So what it is allows us to set breakpoints in our application. It's not the way we are debugging in the front end. Usually usually in the fontent. We hope to have some source mappings so that we can debug this application directly. Let's say in the Chrome developer tools. So no need to open it back to terminal here. So let me show you my application my prosperous. running so I have this postgres running here as In Docker container, here it is. Right. It's already happened up and running you can decide to use PG admin for example to access or to check or debug post, press I prefer on my on my Mac to use a native clients, which is post Eco for it. For example, it's a free to it but gives us a better developer experience. For example, as you can see we already have two entities inside it you can see we have schema definition right structure and a visual way and the content as well. The same applies here for the full for example, as you can see, we already have one data set. Yeah, and we can actually update it directly. So that's this tool. Is this what I'd like to use in this small workshoppy? So pause plus is running. Alrighty, let's check if we have installed all the net required packages. right Okay, cool. Everything works. So let's run it. First of all, it's always makes sense to check the package Jason obviously. All right, so you ever required scripts here preconfigure scripts, I decide to use a star def because it's exactly doing what I'd like to having running to have it running in the watch mode. So you can also use the back for example with some addition debug logging messages, right? So basically this the debug command is setting up and not environment with the back option set to True which are usually enables us enables our application to print a more various console looks for example or logging messages in general. It's like, excuse me about sure. After you run the docker stack deploy. It creates the DB but doesn't create a schema. Right? How do you make the schema? Exactly. The schemas is created. When you start this application for the first time got it. Thanks. So yeah, we are here in the microservice. There might be events API application here and when you run young start if let's do it. And you see if you've seen for a while debugger attached. so no errors, and you can see a lot of right and lots Of logging messages which are somehow related to the database as you can imagine, right? So at some transactions start here, we do some checks. If actually everything is up to date for example, and we start with transaction and women with transaction we create schema for us. Or office type of creating the schema for us with what we set up here in the app module right synchronized group. Right. So we that's a good approach because our application is running in the watch mode. Whenever we add for example a new entity to actually application. So when you class which actually represents a table and all in our database or should represent a data and what database this change is immediately synchronized with database management system our database actually in prosperous. And so that's the synchronize true very nice development experience here as you can see. It's a service application starts in the back mode. very good neat way to debug things or find errors Now application as soon as possible. Let me give an short example. For this maybe we have here this app controller. Right here. We have this get hello operation. Let's Put it here. and start on Local Host before so sorry pal. I've never used an sjs and I'm getting the nest command not found. What's the library called? Exactly? It's Nest. Yes. Exactly. So maybe let's go to the step step by step. So usually in order to set up something. Yes, let's make a short demo. Tnp, and then set this TMP. Let's create a short application Nest you that's name it. This will create a new Nest application for us. Here you choose this node package manager you'd like to use maybe on if you'd like to stick to the same as we usually using and very export. this would Actually, this should set up a complete Nest application for us. The breathing while it's installing a brief history. to an sjs, basically nest Is yeah framework which is built on top of existing and well-known libraries the wild in the note which existed in the note word forever like Express. For example for creating best way apis, right easily. Usually you use express or one way to do it use Express in the no chairs work, but it also introduces a good a lot of good practices inside the word of node.js for example, starting with a programming language itself. Like we'd like to use static type checking with typescript for example, so we don't have to deal with this issue to set app script on our own business backend World here. And also it's also a little bit around the ideas. We know from different Frameworks in the backend world. Let's say it's Springwood maybe of a Java Enterprise stick and also, angular for example, so if you're using angular in the front end and you know, you've seen quite a lot of Concepts which are almost the same here in the sjs worked. For example, dependency injection modules components instead of components. We have so called controllers here. And services which are also injectors, but we'd like to go through this details step by step when we focus on API instead, but basically Nest JS is let's say something on top of existing and when libraries like express passport with a very neat setup typescript, for example build around with best practices in mind with a very we're working CLI. So comments plant interface you can which you can use to create artifacts called artifacts, you know application and so on and so on right but we focus on it later. so let's go back. to the next chance, so as you can see I have Executed or I asked for localhost 3,000 here, right and somehow I ran into this breakpoint. Alright, so it's in here I can debug so certain things maybe. Alright, so as you can see in that this so basically the instance of episodes I'm looking for through I can see what's actually inside it so far nothing special. But I can back step by step usually using my visual studio code. Itself, no need to have console locks of things like that, right? It can be done directing that ID. Oh my let's move to play much. So I have my application up and running. There is a special. Yes, you can see this hello world. Where is a special endpoint? I'd like to show you here. It's graphql Whoa, what is this? This is actually something named playground. It comes with this. Nestjs graphql package, right? So you installed this application this full loaded web applications inside your endpoint. Why using best Nest JS graphql audio? Just remember it or to recap it. Let's take a look. You read this. Type 1 module for root a sorry. No type on graphql module for root here. You will set up this graph here module and you can disable this playground. Using this playground property if you don't like to have it. for some reason just set it to force. Usually that's exactly what I do. Right, you can do also this kind of setups with property to set up this properties this host name port and and this configuration you use it using environment files the configuration files which might be based on your environment. environment variables for example But for us, let's keep it simple. All right, that's hot our configuration Okay, here we go, as you can see whenever I make some changes to the code. It's bids automatically because there is a watcher running on it. I guess, you know, you know this developer experience already from react for from angular and other content related Frameworks right where you usually have this development server with within which watch mode running. Okay. next thing to focus on This will let web application. So let's close API. And let's go to web. This is a typical. a very typical next chance setup with the typescript template Right. It's created as already. Let's put it here in the chat. It was called Channel. For this but how do we join the Discord Channel? I don't see the ion CJs workshops Are are as minus workshops. Maybe I send the direct link. Somehow copy link, maybe this works. Thank you. Do you visit try? That's for you. They can post the common. It's Yeah as well, so no need for you to create this application right now, right? So that's what I already did for you. Right running. Npx create next step. I use the latest version the minus minus TS, which says, okay, let's use the typescript setup. And I like to name my application micro events minus 1. That's what I already did for you with some basic implementations. with some basic configurations Let's go through this basic configuration. Most a little bit more important. and And what we've seen in the API because April those configuration we didn't seen in API mode you. A well-documented directly on the sjs documentation pages, but this year we have to go through a little bit. But that was one of the reasons why I prepared was application beforehand before this Workshop. So basically we insert the Apollo clients. All right, so let's check the packages. With you and we have this dependency to apologize. And that's the one very important we have to use. And also we'd like to have this. the problem this type definition files using all the tabs for example types we have to have right all types Apollo upload plan where One Thing Worth to mention. I also upload client here something we want really use in this Workshop here. That's that's one way for creating uploads using graphql. Usually it's not handled by Apollo directly. It's an external package getting this which part uploads. All right, so usually we don't have it then enabled by default. All right. So two additional package Apollo clients and Apollo upload clients or like to share. Yeah. That's required setup if you like to do it using yarn. So we use. The oh, sorry, that's that's the wrong one. That's a long run. Let's move what the college? so the code should be oh clients. So wait for this confusion. Yeah it Up, and that's that's the Comfort. It's what we need no need for type definition files because this Apollo client already comes with type definition files. Enable to it. Okay, one one. There's something from cassim mine redirects to fools on stuff, but I can't navigate to graphic. Okay, so let's go to this through the setup one. an amendment minutes right because because before we We completed this configuration part here. so what is actually necessary in order to consume graphql? Based apis. We're fondant right or especially in the next JS application. Right. We first of all we have to install Polo client in the second thing we have to do is to go to yep tier 6 To this. All right, what's on my package folder? We have this underscore app TSX. So the base starting point of our application actually all the screens. We using run through this my app components wrapped into with my app components this is allows us. To add some provider around the required Them Questions components, right? So let's let's for example our particular view or particular page. We'd like to render components can come here using this app drops. Right and we pass through all the page props no need. to somehow to remove them or somewhere to edit them or from time to time. We need them to to make some modification to an to configure our provider some hours. Sometimes it's based on the props, but the most cases we don't really use them. And so we just pass it to the components. But the crucial Point here to do is to wrap all this into this Apollo provider. This Apollo provider asks us for one parameter. This one parameter is the client itself. So we have to create an apologize. All this magic all the hooks. For example, we take like later on to to use for example, they use vary of a use. use mutation hooks, for example Works somehow with this client under which all right. So first of all, let's create such a client. FY creating an additional photo for us with some common settings All right, some common settings. Usually it's not so complicated like this, but I added this file it didn't. a little bit more of a Bose mode for you to show you some things. so basically in the end we'd like to like to use and create an Apollo client. Within link, this is basically a data link data Links of a protocol you communicating through I usually HTTP or https, right? But somehow you have some additional features added to it. Maybe authentication. Maybe you'd like to work together with next out. So very fancy more beautiful. For example for the next year's work to inhabil all of us token based. Token based authentification things. Maybe you'd like to also somehow interfere with this traditional link or already existing link for example, extracting multipart uploads. If you like to use for example this upload feature that's already shown here it uploading use this create upload link. Right instead of this already pre-configured pre-explore existing HTTP link out of my apologize like right. So we use Apollo upload client, which is basically the same as the existing HTTP link, but it uses some additional features like extracting multipart uploads. So we've created this HTTP link and with it we use it. Here, right. We also decide which type of caching we'd like to use. and as you can see right we somehow sometimes Can use this sorry. Where is it where exactly is it? Sometimes we use already created constant here this Apollo client. That's what we do with using this provider. But this is for the front and parts as you when maybe already hurt. We usually use next.js to decide where we render things. However in the clients when the web application certain browser. With this is the traditional way, but this way as you maybe already know from create reacted almost everything to all the heck action happens in the front and the web application in the browser itself. All right. But sometimes we'd like to use something like server-side rendering and we decide to render pages. On demands whenever we're requested imagine you have you you're building an application like Amazon right where you can buy a multiple books, for example. And you'd like to share. a very specific books identified by a given resource identifier the URL usually And use you send this URL to a friend for example, maybe using Discord. And what you see here in the description chord Channel, you see a small preview of this book. So, how does this magic? Works actually so that's called knows which book to watch which picture or which preview title of pre previous description of this book to show usually you use something like open graph. Which is based on metatex. so meter text Are some some special html text right which you enable in the document to be delivered. So it's not possible to it is possible. It doesn't make sense. To to add meter text. Dynamically whenever the application is already delivered to the clients instead of it when I send here a link to a very specific book on Amazon. That's a reptroller an agent. of Discord scraps with a document behind this URL looks forward with specific meter text. extracts information inside this meter text and shows the information here as a small preview. All right. So for such techniques, we usually have a need Force maybe server-side rendering. and to deliver already a pre -rendered document with this meter text which are very specific to them book shown. What's wrong, right? so net next year's exactly allows us to do such things like rendering pages on the server on demand, but sometimes also statically so usually we render pages on demand Which are based on a maybe ID which is somehow encoded in the URL. So as you can imagine we could have an endpoint slash books slash ISBN, which already identifies for books for such scenarios that I might. It's pretty much sense to do it on demand, but on the server. To have as meter text enabled. But once it's time to tap, like maybe the homepage or the start page of our applications, which is always the same not really based on any inputs not really on any URL or very parameters. It makes sense to pre-render all of this. On Big Time, in this case. We talked to talk about static static site rendering. So we have this one object. The default option is to render on the client itself. The second thing which might pretty much say is is pro for preconfigured. Pages like maybe the dynamically created pages on demand and we use server side rendering. Otherwise, it might make sense to have some static site rendering done on a base on static resources. That's what we have next year has four. and this client has provided here. is for this front and use cases only so whenever the application is already delivered to the client with web browser and is already running in the web browser. And we would like to access the graphql API from the application running in your browser. when under the hood this Apollo client is used for all the other reasons server side trending static Site range you have to create. Your own Apollo client, which is executed on the server. So in the no chairs environment. basically Therefore we'd like to also use heaven. A function to create such clients dynamically. Maybe on the server side whenever we need it. Use this function Apollo client with token to create such apologize. So that's the basic setup. I already did. And let's see some magic. Okay. We have this API already running. Let's start performance. Yeah. if All right, you know just let's take a look in the package Jason. The scripts area depth Next Step. It's pretty much sense for us. So let's start it. Okay. All active Foods. So now for now we don't have any foods. Right. So we see a page we've got also a redirection open local hospital and one and I've got redirected to food. So where does this food comes from? Actually, there is a configuration file in next. next config.js right in this next Jade config. You can pre-configure some redirects. That's a good practice. Instead of having a default Resources with traditional home component. For example, it makes pretty much sense to think in features. Right. So have a dedicated you have for each feature and your application and make the decision for the user which is the what feature is the first one which should be entered when they use us to go with with an empty road. So empty path that's an area. So whenever I use a course the amplifier, I was scenario it like to access their Foods teacher. Okay. so all things are already working. I recommend. A very nice. plugin for extension actually for Chrome Which is better polok lines they have tools. So it's located here. right and like I entered this page slash who's those two queries have been executed. all active Foods Yes defined you. right with no results Sorry. Yep, just data no results in our scenario. So why not? So let's talk about the API first. Correct. So let's go back to application. And see how it behaves. So I recommend to use a more sophisticated clients instead of this playground, which is right there. Right. Well, if you it's an open source tool and one of the best features of this tool is auto completion. So whenever you write your queries, you don't have to type a manually instead. You just select paste on a schema you selected fairies based on the schemas. So I already did. At two of them or I created already free. Sorry free queries. The first one is all fools. Let's make that executed. As you can see I get no results so far. So let's recreate this Arc Foods, very again. I start by entering feeling. the schema fire Which is localhost3000 graphql. I make sure I always have latest version here of it. and here On the right side. I've got the documentation for the schema divided on the two categories query and mutation. So, let's see which varies are actually already existing on API. Foods and fool fools is for accessing the collection of foods. And fool is for accessing a very particular fool. right So what is the food? a fool is basically an entity with an ID with a very fancy life property and text. Which is a string. And a relation to bar so we have fluent bar application. bar is something which also has 90? life attributes and texts and a relation to the parent food So that's but basically a food. Let's go back. And create this very at query. Here we go. Let's decide from a bus, you know already want only want to access ID and text. It's executed. It's exactly the results. 807 milliseconds ago So the current one. Okay, no data doesn't. create a high end not will you solving on it on the The name of a client is Apollo clients. So we have probably somewhere on a big point or something. Let me check first. What's what's the issue right now? Okay. No, it's not so I'm not sure why it's this working. Oh you would here we go. Here we go. We already have some data inside. It's so probably the database was not set up correctly right now already have some data and settings. So let's run it again. So here we had. What is going on something is happening? Here's our getfus. Let's run it again get all of us it's a very Right. So let's execute it once again. Okay, empty data set. Because I had emot. What window open so now it's everything is fine. So let's create a fool. Let's go to another window. Go to the docs to the mutation. And say we'd like to choose create food. at very here is the mutation. Let's give it a name. Create who Maybe? and this could create full requires us to pass a create full input which is basically a text. and a bars array and the sparse array. This each particular bar out of this bar array as a text field. So let's pass this. First of all, it's stacked with it texts. Let's give it a parameter first. So create food gets the text. Just a string. which just requires next you think we'd like to have the bars area. pictures of type create bar and Not entirely correct. It's actually an area of create buying which. each create bar input is required. Not optional and also the bars areas requires. Let's pass this text variable here. inside this input Text here we go narrow and pass. We'd like to pass here. pass Also the same stick let's decide what should be the result of this mutation. I suggest to keep it simple. So it's Nest too much so from the past we'd like to get ID and text only as results. So next thing in order to create such a fool, we'd like to execute this mutation with values for this variables. Therefore you we use this parables. Let's give it an example. for text you'd like to say. super 4 bars like to give an area each area is actually a create bar input. Which ask for a text? Let's say. Hello. Let's have another one. This hello. Workshop So let's execute this mute. Just created mutation with this variables here for this inputs of this mutation. Well, you've got the result. Let's have ideas been created for us the live objects when this object has been created and the last updates then timestamp are created for us on API. So it's not our control. It's something done on the API side and the activated at this now because this is active object. Listen just created for As you can see also the text field here on this full and where relation to the bus. let's with all this asked values So our API is working when we go back to our Foods. That's executed. It it got also the same database. So what can we do with such API? how to access it from this next shares application in order to work with it in a very with a great developer experience here. I created. A graphql folder with the queries. All right. So a dedicated folder for just for all this great queries. We already have let's see the examples. All right, so just an constant here. or active Foods and I use this Tech graphql. Form was a polo clients which takes a template. drink With our very inside it so basically the workflow is to try some. Queries here. Copy paste this query right copy it. If you're sure that's exactly what we need. We copy it here and paste it here inside the string for this block here. I take we save all this in a constant. all active force in our case I did the same already for create food. for creating one that's exactly what you've seen so far and for find food by ID So later on I'd like to use this queries and this mutations whatever it might be. So I have a very special year or mutations. I'd like to use it inside my react app using the new scary and they use mutation hook. Okay, but there is an issue. with now with this used Ferry and misuse mutation hook well written in a very generous way. So basically when it returns some data. What is data? And what type? is data Right because we do in JavaScript we have that duct typing right so we don't read care about this information. What what is what is the type of data? But here the typescript context we usually care about and we'd like to have a great developer experience using let's say intelligence. Right existing skill certain fields of the results of this query and so on therefore we need type definitions. for the results of this experience As you know as you see and it's it's a little bit different as in traditional rest apis. Usually when you use restful apis, you know, this call returns exactly this results of this type so you can give this result a type you can hardcote in it your application. Could say it get all all active Foods response or something right and program you interface. But it's not possible to do it in a very general way. in graphql to model this response object this domain objects because the type depends on the request itself You can have multiples create full operations or mutations. Sorry. Which return a little bit different results based on the query itself. or the mutation and stuff that's so it doesn't really make sense to introduce here now our font and application a full interface. Because we don't really returning a fool here result of this create full mutation of active Foods. It's really depends. For example, I could decide to say okay. I don't really care for this class here. I don't really care for my ID. All right, and so for this very particular. And query I need another type as a result of a used very hook to use. So how to do it? The worst thing to do it is the worst approach to it is manually. But luckily as we are apolog line of Apollo projects gives us already been necessary tools for it. They're well documented in all this is just called generation. So basically Now by looking on the source code Looking for all this gql text. So based on this Q gql text. We'd like to generate how to generate based on a schema as one input. And on our query as a second input, we'd like to auto-generate type definitions. so therefore I also already pre-configure for you. two additional Scripts So usually you could you don't have to really call a hard coated and even to this scripts area of your application. You can memorize it somehow or write a shell stripped to simplify your work. Basically the idea is to download a schema from an endpoint last recent one. So we're already running active scheme and we'd like to download it. Right. Let's do it. Another name graph screen graphql schema. Let's download it. That's exactly a pearl service download from this particular endpoint. Another script you like to create is coach generation. Alright, so first of all, we execute here and this gql code generation this downloads script. So we are very sure we already have this the most recent schema file on our And ourselves called here of the front end then we use again the Apollo clients of our polo tool command line tool. But in this case we use codegen generate. With from now a local schema, which we already downloaded. It like to generate code for typescript. All right. It's very important to say it here. That's it's typescript because Apollo command line tour works for swiftfox Apple for iOS files or for Android generating cotton for Xbox for example, and so on so it's a very generate tool but we're working in typescript environments. So we'd like to generate typescript code. We'd like to. Consider as an input for code generation everything which is located in the gql folder and it has a typescript sufix. And we'd like to do. And it's based on the gql. Gql Tech so obviously no code which is usually to be memorized instead of rely. I took the commentation. Okay Apollo projects, right this this is very weird documentated how to generate code based on a schemata and based on our existing code. So let's run it. The first things we have to make sure is that our API will our graphql apis already running. So let's take a look at its the case. Yes, it is running right? So it's a running project then we switch to a web project again. Let's kill it for now. And let's run. Yeah. So now we're on. gql code can so GQ and code get so as you can see, it's already downloading the files. And it's auto-generating typescript. based on our queries. So let's take a look into the generated files. No, no really need for it to do it. So but just to give you a brief idea for example for office or active Foods. Right, we've got a lot of tabs starting point is here all active foods, which has this full array. All right with which is off this type. And we asked for this fields. for each view for each food So for example the boss. It's getting here. That's exactly what yeah, we asked for. So we can't really cannot really introduce a general bar interface here. We have to rely on bigquery itself because this very asked just for this two fields. Using Code generation here and that's my way to go. so let's take a brief look on how to actually access. with this data Here we have a page. Right as you may already I heard of maybe in another Workshop or maybe you already had some experience with nextgas, you know, this Pages folder and graphql. Sorry next chance as a very specific role. So everything which is located here under those pages folder. Is directly reflected to our URL or to the path actually, which will user puts in into the browser. So we accessing here this full path. And inside this Foose we have this index file. Which is basically the local horse. Free thousand slash Foods. We are addressing this index. Yes. So let's take a look on this fools. And we have this awfuls page with this and tradition next page. And here we use this use very hook. right use Query hook it's a generic hook so we have to Pass the data types as generated. For us so our active Foods this exactly what we are asking for the types of a variables. And then as a parameter to this query we pass. The query itself, right? So here we go. Let's look very very passing experimental. Sorry. So let's go back to index. Here, we have a variables if this all active Foods. Ask for certain variables can pass them here using intellisense like skip or take let's take a look on our all active Foods again. All right, all active force and our case uses a Skip and take parameter which is passed to it Vari itself as a range range property. We haven't seen most properties before it because I this one when I already hardcore it here until this seed project is differs a little bit from this what we created here together. And so here we have some additional properties right for the common property for a common property. We said we'd like to all only have active. Foods we'd like to ask for food because it returns a large potentially a large area. We'd like to skip somehow. Some of them and take on even maybe 10 and to to work on a such let's say pagination use case, right? So that's exactly the parameters. Which can be passed with every year. right so I can also skip use it until he sends. Say number one on interested in having 10. Foods right the use very return and object with a lot of data or a lot of properties inside it but for most use cases to be honest only free are really important. It's the data itself. So it's all we're using the structuring usually. All right. So we like to access the data. It's give it this data and a meaningful Alias name or active foods, for example, a loading flag which indicates if this operation is still running. It's a Boolean. Right and an error flick which contain which has the error in error case, but they haven't used it in Mobile my empation. So as you can see here Right. First of all, we are lying on this loading field. saying okay in case if this is loading saying loading what? my wife assuming all active Foods Has some data in it, let's map each of us Foods right to some. to a full and displayed some basic information for each food. Maybe the idea itself. speaking example, hopefully our application will show something right now. Because we already created in our API. Completely, let's make it sure but we already had some data inside it. So again all fours. Let's execute executed again, so we should have one full inside it. All right. So applications running. Let's go again. Who's Here it is. Okay, next thing we should know. I also already created another page for a very specific food. Right, so I say like to pause for ID. Of his food here. as but in the URL and this is a result. I get the detail view of in this case. I also render only the ID with us with a text of this food, right? You just can remember I was full as a text property and this is rendered here idea and the text. But the implementation is a little bit different. So let's take a look on this first. And let's take a look on this first. Here, I'd like to show you another technique. so let's assume. I'd like to share. this food with you maybe in this course. In our case is one one really render some anything. friends here one friend anything at all, right because I haven't configured so far but what happens actually here when I share this link with it, whoever wants to join a see this this This document behind this URL gets a view. for a very specific fool endless view is already created on the server for you on demand. Right on demand. So it means okay if it's the first Time I share a URL like this with this hard coded uuid inside. It is page is created on the server for you with potential some meter text would show up in a very nice preview here in this course, for example so so the technique here use the server-side rendering on demand, obviously the way to do it is to provide inside the page. TSX file it gets server-side props. function Right, so exporting to things here inside this ID TSX. First thing we explore exporting is the full page itself. So here this As you can see we rendering the full ID and the text. So that's exactly what we've seen. And we expecting a full parameter. for this full page and this full parameters of tight fool, which is just a type areas on office very specific and auto-generated type Right well because it depends on the query. And so that's what actually like to pass with full page here. As a parameter. And I like to do it on demand on the server. Therefore. I provide a second export which is that gets server-side props. That's an async operation based on the context the context. And I can use a context in order to access preparers. Right. I can use context parents in order to access the idea of ideas here hardcoded as an information into the documented resource file itself. That's the way how and next year's work. Right? So this parameter information hardcore hardcoded inside this the final answer. I'd like to access this idea and I'd like to treat it as a string. So as what I've been doing here. Is to create a client. Why don't I use the use Query? because this code is executed in the back and it's executed on the server Right. Let's executed as a note Js. Script in a node.js environment. It's not executed in the browser. It's also not executed in the react context which runs in the browser. So it's basically just a usual. Usual or traditional function. Let's say name it like this which is executed on the server. That's how the next Jazz works whenever it finds. This gets server-side props function within such a page file is function is executed with this context of this next year's application. Therefore I have to use the second utility Apollo client with token. That's exactly this function. I have shown you before one of this. Possibilities to create such an Apollo client right whenever I need it. So it's another one. It's not the same Apollo client as provided using this Apollo provider. And so if let me show it again once again, alright, so we've seen this up color provider and we pass already Apollo client and set it but this Apollo Clan which I like to use in this function as shown which just shown is another one. This one is always used in within the hooks in the front end. But I'm recreating one. On Demand on the server Within this gets server-side props here. And use some somehow similar approach. To run queries I use directly you have client.query. Also passing a very specific Ferry. I'd like to use right Auto generate types here. If it's query here find full by ID passing the variables inside this as you can see, so it's the code sum over the similar somehow similar is to the very use Query. I'd like to access this data and the full to get this full out of it and I like to have this full. as a prop as to be passed as a prop to the full page. So with Theory receive this form. Okay, I brief look into this. Okay charts this I must have missed something. I am seeing a polo not found when running that g gql scripts not seeing Apollo and note modules. Yeah, I know you mentioned this a while ago. I was just trying to debug it while you were going through the other things. Oh, yes selling Apollo globally. When I do that, I'm seeing graphql certain graphql validations missing, but I'll do it again and okay. Okay, installing globally and then I'll let you know what there is exactly in a second after this. Okay, cool. Yes, actually that's something I forgot to mention right so I probably am missing here dependency in the package Jason And probably so I've installed Apollo globally and I cannot find module graphql slash validation slash rules slash known argument names rule. This is when running gql download schema. That's also not it's also necessary to have this gql. So it was kind of a specific version. It's I do have three five six in my language Jason having that changed a lot aside from installing. Maybe maybe what do you want to share your screen with us? Sure. Okay. I should change my resolution before doing that because it's quite a large screen. So give me one but 30 seconds. Okay, let me know when you can see this. Okay. This is what I was here. Just installed the Powerball. Three be on any specifically I've seen this before I've seen I've seen this before. not sure what what resolution was I think Yes, everyone's are installed. Yes node version 16 someone's asking questions to chatosis answering. So I don't want to hold everyone up. It's okay. I'll just follow along and see if I'm interested. Yeah, but I think it's a solution was to somehow. Instant exactly this dependency which is missing. Yeah, okay. Well, what graphical versions We have probably I said, I'm sorry. You said globally? Yes, globally because you're running here. Yeah, because he runs okay. All right. Yeah, maybe maybe. All right. I don't want to hold this up. So okay. Great. Okay something. Okay. Good. Thank you. So you should see my screen again. clean Okay, cool, so Bye by the way, by the way This year with us downloading and this code generation and so on. It's a traditional approach with what works for some. For a while, right? Maybe for one year. I'm very successful with this code and that's exactly the code is it's documented on one of our polyplo projects, but they already mentioned there. That's that's a candidate to change. So all this code Generations such a cool thing that they actually like to somehow simplify our office. And so this is actually a candidate to change the future versions of a couple of plants. This approach of work is called Chen and generators and so on. Um, by the way, I also have successful or set up for Swift. For example, if you're developing for example native iOS applications. It's all generates Swift fast for you. What's with types? Sorry for you as well. So it's it's a really cool project my way. Okay, let's move on. So again, as we seen another way here gets server side props to let this piece of code running on the server on demand whenever a new URL that's this excess. Basically, it's some caching mechanism involves a lot. Every time this this path is is executed this function runs basically also their outcome of this right office preview office service center, and that document is cached. Right with the time to disconnect right? So let's it's kind of performance. If you'd like to do it on the client side again, you just access my ID itself. All right, which comes directly? Which comes the sorry you use ID, for example, yeah. Right and use traditionally we use fairy on the content. One Thing Worth to mention if you do it on the server side accessing graphql the graphql APR on WhatsApp server. We won't see anything here. Right, you want to see anything here or active query is not no queries at all because what we see here are the queries in the front and application. That's the react context. So in the Apollo clients as provided by the Apollo. Yeah kind of provider. Right, but here we execute it very own server. On demand, so no queries shown here. Okay, cool. I think basically. That's the first part of this Workshop. right Toto somehow if this code up and running get some basic understanding what's actually going on in the front end. Right from now on we'd like to implement our very simple Microsoft. Sorry Mercury events applications. So basically we'd like to write extend our Graphics schema down, but API side. And like to introduce you some queries in order to access all the micro events. We'd like to introduce a mutation for creating microservice. Right and really also need to do some work on the API as well. Actually one thing I forgot to do to do with you you so far to take a look on that API API code, so we're back-end code behind it. So let's let's do it first. Before we go to the micro events application. So on the API on Project here. We have a full volume. Alright, so each module in an SJ applications is as a modifier here this export class full audio events and typescript decorator with exactly one pyramid parameter. And this one parameter is an object literal or an object generator with some setups. All right, so some key values. All right. So usually the key is from the left side, of course and override set. We have usually the value given as an array not always but most cases for most Keys was an arrays. Here we have some providers. provide us right here. I don't want we talked about dependency injection in general. But basically we have this version of control approach. So let's just application is running application and running container without your code without you actually called artifacts given it already runs. But you provide some code artifacts playful feeling a Content kind of a contracts. And Nest J has whenever it sees some of you. See some of your provider artifacts maybe your full service. That give in a given moment on time. It creates an instance for you provides over dependencies for you. So basically the instance of this full service is an object and so quite managed object with this maintained by the framework and not by you yourself. So you're not creating Food Service instances on instances on your own. But in SGS is doing it for them. I don't really go to too deep into the idea of dependency injection. Basically, we need to fill a complete workshop with it. It's to get some understanding for it but the way how it works is that we have this one module for this full feature. With some code artifacts inside it. In sjs, has this very fancy naming convention. Yeah the findings you see one dot with all what he has thought service. Yes, not modularity. Yes, technically. Those are all classes right typescript classes. But in order to get some understanding what role this class has in your application, we give this event stereotypes. To identify for fast as programmer so that we can identify the role of this artifact Discord artifact usually a class. In our application, you know in our code base. Sorry. All right, so we know this full service, which is basically a class. Right is on stereotype service. So in a multitire application usually having some persistence layer and we have some domain layer. And then we have median API layer which exposes the domains somehow to public. Right services are somehow located in the domain layer. So by dealing with so called entities. So here we have our quantity. Right and get regular class. Which extends a public object? before we go into the details of this full class. Of his full entity. Let's discuss the public object first. What is a public object? basically It's just an idea idea how to extract some commonalities in our code base and into a base class. So basically as public object is an abstract class so generic abstract class it has this ID. and life so the idea is for is that every entity which is exposed. Or as a candidate to be exposed to the public as a graphql thing. Right. It's the public object as you can imagine how I relational database. I mean no relational database schema. Let's say it like this. We have some entities. It shouldn't be exposed to be public. I mean we need them maybe for technical reasons right to have some relations maybe in between different kinds of entities, but there are aren't a candidate to be exposed to the public. But we are identified in our application. But public objects. So those objects which are candidate to be exposed to the public has have some commonalities. basically and ID Right. So all the public objects with dealing with have an ID. We also have this fancy life objects. alive means we have this created at timestamp updated at timestamp and the activated timestamp. As we learn in a second also those fields. aren't really there's no need for us to manage them on our own because they are how to fit using this type of capabilities So let's create a date calendar The Decorator and the update can decorate account from that type of packages or provided by type on so we don't really have to care about this the values of this created at times and update at times and whenever we update or create. An entity using the so called entity manager and the typeworm world. Both fields for this instance are updated automatically for us. the deactivated at field not really. So that's a strategy which is very common. and in application development in general maybe for prior form. for legal reasons Right. So as you know today we can't really not really allowed if we want want to do so delete data. We have to keep to keep them still in our database somehow for some some reason. It's a great criminal activity happens, right? We have to keep you still have them so and and so deleting. Instance out of our relation a database usually leads a lot of problems right because as the names suggest it's a relation a database. So there are potentially a lot of our entities which are related to the object to be deleted. So the delete operation to implement is not an easy one. So that's a cool trick to keep track always on such objects at deactivated at time stands potentially, which is an optional so it can be malleable usually by default. It's valuable. So it's an active object because the activated has now and we consider as the actiated at property running a secret queries I always ask the activated now not equal to now. All right, in order to have one even active ones. It's much cheaper when dealing with this complexity of deleting instances usually So we set the public object is basically. Something which has an ID. and the life also the ID Is created not by Russia or by us, but also how to generate it. Here we also use if a cool capability of on a utility actually of office type 1 Word. to use generator for auto-generated columns What's actually possible here inserts? Let's take a look. You had the row ID increment identity potentially or well known database Management systems that my SQL Oracle and postgres and so on being always incrementalist Auto increment thing, right? for public objects we Want want to have something like you you ID so not really predictable ideas. All right, so it's also for security reasons, but also the identifies is usually very nicely. right some fun somehow in the US it's uuid has to be supported by that by the underlying the data and data management systems base management system under the hood and possible supports. It's very well right out of there out of a box. So it can be done here. so before we jump into this annotations Which are important because we have two words here with this annotations. Some of them are for graphql and some of them are for type or and here's the good news. usually the idea become behind this decorators as In the typescript, sorry the type of words. The ideas behind it are the same as the graphical words. So you can establish some some kind of a pattern you have right in order which which decorators are actually needed in order to have the same class for your database. for type 1 S4 graphql so Yeah, I said. Okay. by Foo Is a public object so it comes already with this ID property and it comes already with this. With this life object, but additionally to it it has this text property. and this relation To the bar. property right as we yes as we can see bars the public object. This web. So it has also an ID of type uuid and this fancy life objects. Additional column maybe the text. And a relation to the parents. So basically it's a b directional and a relation. Right? So it's very and necessary while modeling in graphql to say of relation is unidirectional or B Direction. Also, depending on this information your clients this annotations a little bit different and declarations a little bit different. It turns also. Turns out also to be a good idea to have in case of relations. It's lazy flag set to true. What does it mean? Usually when you use the so called entity manager for accessing different foods. That's if different foods, right? So you get an area of force as a result. You don't really load for each of the force the complete. because it's a very expensive operation. Maybe you don't really need the boss. So let's let me give you an example. Here I have this all foods, right? Let me send it. Oh, that's why this is empty again. Because I recreated well, sorry. So like again, let's create a fool. It is powerfus. Here it is. So to access this bar this very expensive operation at this turns out to be right. So we accessing each of a Foos first and then for each of the foods we have to carry the database the game in order to access the bars. but maybe I don't need to pass. Maybe I'm not asking for them. right Why should I carry? response anyway Right, so it turns out to be a good idea in a graphic a word type arm is not binded to type or type. Sorry to graphql but in a graphical word, it makes pretty much sense to say it's always relations. lazy so on demand So therefore lazy and operations are always promises. So for this Asian world only resolved when exists. Okay. so let's go through some annotations. The most important one is entity. That's from the perspective of type one who should become a table. So basically it's not a completely true entity and a person from a perspective of system architecture. It's an entities or somewhere and domain driven approach. It's some some kind of a business object, but it also means from a perspective of time on Hey type on create table for us right actually, let me say take a look here. We have exactly this full here. Right. Here it is. And ID created at updated deactivated at so this at entities States. It's an entity Creator table for it. this column Says, okay. This is a column of the table to be created. It's not malleable. Right two words again. You can make a lot of mistakes here. The most prominent mistake is to say okay here. It's an optional. And here's a force. Right. So actually it doesn't really match. So from the perspective of our compiler from the perspective of our typescript compiler, that's an option. It can be not well and yeah, well undefined right but from the perspective of our schema, it's not valuable. So this isn't common mistake which at runtime always consider the typescript. It's a build time only story. All right. So at runtime everything is Javascript. So it's runtime you don't have information with typescript information with static type information that it should be but it's potentially a an optional or not. So always make sure to have this. Here in zinc. All right, so it's not malleable. So it's awesome. Not an option from a perspective of typescript make sure it's it's so that's the column perspective of if the column of a perspective of typescript one too many. Also something which comes from with type 1 which means okay. this boss I represented by the bar entity. It's a b-directional entity the relation so it's a bidirectional relation. So when we have a particular bar this fool, we are inside this instance of work is exactly it's somehow related to this dot fool, and we already talked about this lady. so cool But what is this? As it turns out. graphql has also some kind of Declaration to decorate I usually Object type comes with entities so usually when you have here this entity you have this object type from a perspective of graphql. So with object time, you also said say, okay. This year should become. Part of the draft schema, right? If you forget this object type, it won't become part of the graph here schematically completed this implements here. Is also crucial. because here and this entity says okay we have An extensive relation with a public object. But there are no extent was come no inheritance class based inheritance. In graphql, but we have interfaces and graphql. So this public object is also. Right an interface from the perspective of graphql. Let's take a look on it. It is interface type. comes with graphql right and we're saying okay. Public object so usually extensions years. Sorry some inheritance class space inheritance comes together with implements. The property of object type and here you see the field. So of all Yes or from a type type on perspective Force decorators might be a little bit complicated from a perspective of time. Sorry graphql. It's quite simple. It's always named at field. And as you can see those fields match. This conversations match. So we use insteading here. It's very and so on and so on. quite simple right here. So what can we do with this public objects? or first of all Where are actually or our? operations implemented so where is the storage of accessing office this Entities, where does it happen? Usually in them. attached services here the same idea. So basically service are technically injectables. So using dependency injections up system. Right, and here we have you have. a couple of methods a good pattern here is to have always entity manager as first parameter. So here you have insert operation for creating a new Full for example. All right. We are passing the entity manager as a perimeter. within input our input is part of the schema of a graphql schema. input type the graphql input type That's exactly the object. We're passing here. some implementation No, we want really focus too much on it. But basically we using entity entity manager for creating new instances based on the input. Also the relations in this case the bar and save it in the end. Right? So with that we have already in the managed two objects. There's an outcome. With authentic generated inputs IDs. Sorry the timestance and so on. I like to give you Also a good reason why we'd like to use this entity manager here first parameter. Instead of let's say injecting the entity manager are using nestjs on facilities like repositories. For example The reason for it that we can find great work with so-called transactions. So imagine you have operations using for example Food Service. Also the bar servers you had multiple inserts and so on and you have want an atomic Behavior. So what you say All or Nothing. I want all this operation are run successfully. Or everything should be right back in such scenario. You don't want to have a regular entity manager here. but here's the resolver. You use a transactional entity manager? The past was map entity manager here as a parameter. The reason is simple entity service for someone's our service here, which we've just seen can you use our operations of our services which also takes the same entity manager as a parameter? Having this same entity manager always as a first parameter and shows you that you can pass and add transactional entity manager inside it whenever one of this operation fails. and whenever one of this operation fails for some reason everything is rolled back. This is a very cool thing because it simplifies also your implementations. You know some people tend to say okay. The first thing we have to do here in such an operation is to make sure operations are valid. Sorry some we have to validate some things or make sure some things. You don't really have to do it here. I don't talk about validation of the talents to backend validation, which is already have to which already you have to be done. But some things which these with error messages for example, so if for for error medical code or 500 error codes, usually right you don't really have to deal it here in a very specific manner just throw and accept exception wherever your feel so it's rolls you have to transaction completely back. and everything which involves persistence on your database system roles and make so that's service. With an insert operation, but where are the query operations? So as the Sterns out to be it's not public object service, right? So here it's a very specific thing public object service extents. We have already on the base implementation some queries some very common queries like find all deactivate right for deactivating things for selecting things using Cinemas very Builder and even operations like ensure exists of row, which are very common. Right to make sure it's best but requested entity which we will click on within idea even exists. So I don't want to dive too much into this implementations, right? It's maybe something we can do on your own right because it's that does make make sense this cold. a briefing one thing we haven't seen so far. It's a resolver last week. Last resolver is fair. Let's say the firewall right this one, which it really cook this part of your backend application, which talks to the client. Right and here we have this sorry and the wrong one the full result. and here's the full result of application for so name four is over. It's also switch some magic inside that. With some public object resolver for common operations where you name the operations like friend or fools fool. They keep it full. and some very entity-specific Charities like createful right here. We have this great full input. With this transaction manager and here you just call this entity service with just to pass this input. Okie dokies, that's the so-called mixing. I guess now you've seen everything which makes up this small application. All right, it's quite a lot. I guess most of you are already exhausted. or try to follow Right from now on after a short very short break maybe your five minutes or so. We like to continue with our Michael Events application. We'd like to introduce a new entity micro event. We'd like to also introduce another entity, which is user. Right this moment, maybe Pia and our world. Bring them both into relation. So what we have matting? In our database, let's expose this micro event and the user to the public. Then we're done within sjs parked with our API part and then we focus on writing queries. But therefore for writing queries we use the clients. We don't go into the front and application directly, but instead of refocus here on our playground either our playground, or maybe I'll tell if you prefer. We Define some queries maybe some mutations. The Next Step would be to create to move this queries and mutations into the front end application as we've already seen. Here and inside this gql queries, we out to generate types definitions for those queries. And then we focus on the front end development, which is a component the pages. so let's continue. We'd like to create. a Nava entity lava feature and our API application basically now a graphql API. Therefore we start open the terminal, right? This is one attached to API or inside the API project. Basically, we're running here. So let's create another one in API project. Not the back one. What's temporary regular terminal and let's run and Nest common nests here. I comments. So when they CLI, is this Nest here? All right, so you can use Nest G for Generate and then you have a couple of options. Here you become. Popular you have create more multiple articles rights usually for us. Most important one is usually are always so we're not fair on. Rest response, right we would like to create a completely cracked resource with all that and necessary artefacts. So let's use it. Let's generate rest. And net let's name it peer right. I really avoid for you when they the name user of entity name users because somehow it's a very common to term right foot is a lot of things my application and each micro event has multiple peers attached to it. Basically, it's a user. So a couple of questions here. Rest apni no, you're not using one. We'd like to use graphql code first, right? So that's how our approach here. Would you like to generate cracks and Three Points? Yes. Right. So we've got a lot of code generated for us as you can see, right? And also the app module it's updated. Let's see it updated. What do you here? We have a dependency to PM module. So the app module knows from now on the PM module. Okay, we can could do it like this and now doing all things manually. Nevertheless, I I like to use the empty the lazy men approach here instead of auto-generating which is already a somehow and lazy man approach but instead I say, okay. Let's remove the P again just copy paste this food here. Inside my clock and rename it who is appear why because my coats. From this full module is already very generic. Right? I use a lot of things inside it but it's a very generic code. So from now on. I'd like to do some naming renamings. That's so simple operations here starting maybe with a modular from now on. It's not a module, but appear more you. Right here module as we name also the file accordingly. Okay, cool. Food Service It's not a full service. It's a pear service. right and Exactly. It's a piece. Let's rename a file as well. the full resolver comes p resolver this awesome all right, let's Entities, so I don't have so many entities inside this peer future instead of it. I already have only have one. So let's rename this as well. Because it comes here. It's also public object. Let's win the name of Fire. With this, let's name rename do something namings here as well. We have a dedicated type of ID. Right, and we don't have this relation. So what is my peer let's focus maybe a little bit on this. We don't have a text. We already have found this public object this idea and this idea of type uuid, and this fancy life object. But maybe I have a username. And username is a string. It's also required. from the perspective of type on Malibu is false. It's by now. It's the default so I don't really have to write it. But I'd like to be very explicit here and it's a column. also another Force at this the first one is well in required by to be to have as a Field in the graphql schema, and this one is required from type of perspective. Right? So let's clean up a little bit. So basically we are done here with our peer. It sounds a little bit stupid to or lazy to work like this but exactly is that's where most efficient way to code right to do some initial codes which already works for us, which that we inject. Okay, everything is fine. Everything is working doing in a very generic approach. So we're working with mixins working with generics, for example, usually a good idea and being doing some amazing we naming so we have our peer entity. Let's focus on them. Input time how what is actually from the perspective of? from a perspective of graphql the input in order to create not the food. What about it's mean it's here as well. Not the parts or appear. here Germany is already quite late Great peer input. Alright, so we need at these by username. There's a string. And we say okay. It's a field right? So in order to become a type input of this. Office input type input type something which is also reflected in McAfee schema. We need this field. here So it's enough. for this right See, so, okay. So we have this create key input we have this P entity. Let's focus again on the peer service here become Things become a little bit more complicated we have this pservice. Working on the p on the PID. like identifier lock messages appear Anti-relig to focus on the insert operation. We already have a lot of operation here in the base class right find all from very fine or select and show exists of role reactivate finds find one. Yes. I guess it's awesome uncertain somehow select visit. I can't find it. Find one here it is a simple operation, right? So a lot of operation we get get by free using this public object service based class. But here we have only to focus on the creation operation, right? So let's let's coated a scratch create full inputs becomes create key input Okay. And it should return appear. We're using the entity manager. Where you say create? First parameter is very class. We'd like to create here. when we pass some fields right, so the pier has A username right this idea in life are managed basically by by our Base Class so ideas how to generate life as of managed by the base class, but the username is something which we have to actually add here from this input. Okay. Username you this? the result of this operation is appear. Right. So we have a peer instance created using the entity manager. Now we have to save it. right so return entity manager safe here I guess we're done. With it. All right. It's a very simple operation using the entity manager. We use the create operation. Stating which class we operating on appears always the first parameter. And here are the fields to be set for the new instance to be created. Here it is but it's still not saved. So we have you to use them em safe peer and from now on here where the result is right here where my cars are actually is. This how to generate fields are also populated. So we're done with a peer Services where? Let's go to the peer resolver. So we'd like to have a result or the peer here. We provide all the operations which I actually which creates queries and mutations. So we use a public object resolver with some magic. With some magic attached to it. Basically it's a mixing. So we saying for the fight all operation we'd like like to name the final operation. peers To find one. We'd like to name here and deactivate operation. We'd like to name peer a deactivate here. Keep in mind. Yes. Keep in mind that all this queries and mutations have to be unique globally unique inside your schemata. So all you can't just pass your generic names. Like let's say find all find one or deactivate and so on right? So always when naming your operations you invitations and queries and set resolver make sure they are globally unique. Find a good patterns that works for you. also something said useful gaming experience so we have also a lot of magic using this public object to resolver like which provides us some queries and mutations for three years already said now for the final Find one or deactivate right which already Works quite well for us. But at least one specific we need. Which is where create operational but not create food, but create. here this let's name the input somehow. also it makes entities service inside absent key input absured variants upset or meaning create PM, which makes more sense. So peer resolver is I guess done. Let's not fix. What makes up my peer module and our case we need at least this here here. We don't have a bar. Here we go. Here is hopefully done. Let's check it if it work. If look oh something went wrong, so not everything is working. It was pink. I could try before at least actually read reading this error messages is to we start application. Okay, something went wrong. What I nothing what I expected. Unable to bar is not defined. So I have his power somewhere already estimating. Probably some it's a complete compilation error, I guess. entities full entity I think I make made some somewhere steak. but well so that's that's actually common, but Arrow messages You get not really? specific not very precisely and somehow sometimes even not right so not stating. Nine years full entity. There's one thing you can always do if you cannot something out. What's what's the reason for it? Just remove a sort of contest for you. so nestjs manages this folder where it creates its cache right so maybe some in which Immediate results are cached incorrectly. Once I did is already said I moved to module. I recreated we named a lot of things maybe things went wrong. Yeah. Oh, yeah. It was it was the case. So everything worked after removing this this which was also consists the cache. So next thing we can do right now is to check. Postico or whatever you'd like to use. Let's Loaded here. It is. Here is my peer exactly what I expected in ID username created that updated that deactivated it of type, uuid. Everything's seems to be fine here. so next thing to do again back to API and let's do the same almost the same. Know what because we're running a little bit out of time. I don't do it one one more time, which is basically the same operations copy pasting defining ceramic additional columns and renaming Springs. I leave it with with kids right so you don't run out of time. So we have sphere. Let's check next. If it's part of a generated schema. So let's reload the schema. Let's make sure it's done. Here we go to the docs. Sorry. We already are in the docs. Let's go home. And let's see. very who's oh, no not what I expected something when and worked for me. The purple I have to think. I have to think since then. Sorry. I'm also seeing that it's not in Ducks, but I have everything else working. Okay? So what is it actually part of generated? schemata It's check playground Maybe. Not do this. area of well, it's very stated Foods schema. We have a life object is public object here on the right? So that's the generated schema live. the time public object public objects full we have a full we have a bar. very Also, I forgot something I forgot something. similar part of Oh, I know what I forgot. I forgot to put this just generated modules here is a referenced that module that's you just be running and check it. Yeah, maybe again. Now it's here. Oh. oh so Piers Pierre, right and we have also two mutation create peer and deactivate people for us. So let's let's check check the pier for example appear. as ID life and username it also has yeah. Something I'm missing. Oh, no, I would like to check the ferry. Not the very limitations. Sorry the mutation for creating appear between peer input requires a username. So everything is working. Let's focus on the ferries and the mutation of a one query and one mutation. Maybe we'd like to we'd like to write here. so again Docs like start with maybe with Collection of selective appears. I'd like to name it query or yes. this and I try to say, okay. Same at all active piece. or active peace so like this I'd like to have the parameter take or skip it just and it's a question. I'm seeing that you have query all active peers here, but I only have the query objects without the query keyword. This is optional. Online six, so what you have this year? I have run query and I have the object when I click create query from the docs. It creates an object with peers comment everything you have from line seven. I think that's exactly that's what it creates. So again, very peers at query so actually actually it's an unnamed career very it's it's actually that's that's important the state. So so basically this is here. This almost the same syntax. As resolving Fields. So for example This feat let's say username, right? This username could be also a field to be resolved. So we could also write a dedicated resolver for this particular field. So for example username could be something like this where we also pass some parameters. so Graf here is very fine. Grain even on the atomics. So even on this. Primitive data types, even on the field on the leaves of this tree of this object tree, right so you can even for each leave of this tree right and dedicated resolver. So in 12 degrees for example to make some modification for a username To have an uppercase or something like this. That's good could be possible. It's all very well supported in. In SGS or a graphical findings Apollo bindings, Nebraska. Yes, in this case. You're right dedicated resolver for Fields, but you keep in mind that resolving. We're having in such a fine rate. It's always has some costs and so always craft create. With graphql, you should keep in mind that writing resolve us for dedicated Fields has some cost evolved. So it's not really necessary. Don't do it, please. so very or or yes or active peers and with some parameters inside it, what is this common thing here? collection common input is active range order by order by Direction Auto by nice that's already things which comes with comes with this basic implementation of this public object if when the public object resolver, it's already attached to it. so we can choose to have active Always set to true. Now some detective it's it's a union sorry enumeration you active. range it's a collection range, but wasn't a collection engine, but Skip and take let's say skip is something we'd like to introduce. and take this something we'd like to introduce a variable as well. So let's move. No, let's move all this Parts. Yeah. It is an integer I guess. not sure about I think it's it is take this and integer it's also optional, you know by default in a graphql all types are options if you don't want to have an optional but this And forgot to see right here. So this Mark behind it. So let's know variables. We don't pass any we keep it with believe it by default, which is not let's executed Collective peers. Give us your peers so far so good. So that next thing to do is to create a peer. Which is a mutation. Let's go back to mutation. Let's choose create here. And also like to pass the name here. create here Okay, we have one parameter, which is username. Of type string and it's required always required. So make sure. posit here and let's pause it. as well one dollar signs too much I think it's okay. It's try it. It's a variables username. Maybe my name. and execute So created successfully you're this. Let's go back to all right use us. All right. Let's run this query here. So it works as well. So we are done our API or what we did actually tested seems to work for us. So let's go back to our front end application. to our graphql folder here. It's also quite simple create file, which is somehow similar or somehow named similar to The Very itself. So all active peers make sense. Pretty much sense for me also like to start with a uppercase letter. Here in this case. Why because all those names are reflected somehow out in a generated code. So there's also see this. Relations. It's It's pretty much sense to me import from not sure about it the polo client. Polo client It is and here we have something like G ql. Here it is. So we need one constant. and also or addictive peers and here I go to uppercase. all active almost what diffuse? And yeah, I'd like to use a gql take. my script feature With the temperate string was just backticks here and I copy paste. Oh, sorry copy paste. What I just tested. Too many windows sometimes what? So works for me. let me So all active piece number one, we have one mutation. This one mutation is create peer. So let's name it like this. click to You know what? it yes. again the import gqi from Apollo clients make sense export free you gql oops, that's what I'd like to paste. I like to paste the mutation. as tested Here it is. Oh something. Oh const Africans. We keep going skiing. Of course. It's a constant. So I've got this query the contrary and the mutational next thing to do is to run autogeneration. So yarn G Q head coach and generates the auto the queries for me seems to work to be working. Let's start. with a simple page and dedicated folder. Yes. Do we say we need to index file? index TS we are running a little bit out of time. So I again so if all this I make this lazy men approach. And say index is a copy. Well, that's not what I wanted to copy. I wanted to copy this. this one So we have here's page. It was a summary namings. always use this refactoring features of Visual Studio code of uid instead of instead of just renaming right, you know to make sure. that we use the car right data or be a page seems to be fine. Now you Sprouts. I don't need it all active piece. Here it does. Loading or active pools. Let's rename it as well. this is yeah, so the auto correction Auto intelligence is not working. Because we forgot something very important. You're not you should always rely on this data types of tables that excitation checking first of all password, correct? Very inserted which is all active peers. and typings all active years and all active p is variables. Do this. Variables so now it should work. Yes. Yeah, it works. and yeah. and here I so I think we are fine. Let's start the application. which is yarn f and let's check if everything works as expected. So where's my page? Here we go. Who's don't any have any foods? Okay. Yes. We have one active here. Here it is. maybe even so use an important here I am. So time for one last thing. This code here. No. This code here. It's a very good candidate. To be moved to a so-called custom hook. Right. So let's Try this. next let's start maybe a new folder. domain right inside of a domain I place PS so for the future peers instead of a feature piece. I'd like to place a index file and inside that appears. I play like to place the use. active peers PS 5 so for the custom hook. Which is export const use active. Yes. Which returns something we have to focus a little bit on what it actually returns. Now, let's leave it empty. The first stop approach is just to move. What is this index? Oh, no, it's all fine. First of all, where is our? page inside in here we have this already existing code. Let's copy paste it. And move it here. Let's let's Auto Import certain things. and we have all active peers here. So let's define. reside time interface use active yes result. where we have this all active piece but we don't really care about the small active PS we care about the peers inside this all active piece right because so yes of type all active peers. peers don't What really nice too nice, so let's define also type them but type audio is type. here nap. Yes. Let's say here. We have our piece. Also like to have a loading flag. all type Boolean and an error flag of type Apollo error Here we go. That's actually my result type. Nice, make sure to return exactly this. So we are returning. peers Oh, no, it's not. That's correct. data Yes. Not sure if you can do it like this. Okay, so let's say Union data that doesn't make sense. So let's twitch completely Data, yes. Of course this PS might be not loaded. It's the loading. Yes. Mm-hmm. so Now we need this loading operation. It was loading and we need Arrow as well. So some mistakes the new I mean. Of course. Yes. It's a piano appears. right and here we have This things okay not make sense arrows and Apollo error, but here it it's an option of you obviously not always have no error. So we have our custom hook which states exactly what it does. Let's use it. Simplify what to clean up our code a little bit. piece active peers our case with loading it appears. You can simplify as well. and clean up our Imports. so Use active peers. Will find here as well. I don't like the import. All right. So use the index file export. from positive peers back again new important directly from peace So basically, that's it. from our Workshop Do you have any questions? Or something in mind. Would you like to say? So I guess it was or is very intense what we see. so far what I like to do. After this Workshop is to commit these changes and what we developed here together. But you can see it's when you find some generic patterns for yourself. how to simplify your work As I did. for example in the API Connect with API. with this fool with this commonalities, right? So where I set? Okay, there is something like a base object like a public object something which is exposed. Has some commonalities. right, basically ID and the life object It can be expressed. In typescript in a very generic way. also the service and it's operations. Can be expressed in a very generic way. and a resolver Which is basically working on both of this. We cry as some. Advanced typescript knowledge and how to work for example with mixes that just one approach how things can be done. It can be done in a much simpler way using inheritance, but something set of makes sense choose an abstraction, whatever I would like. also we've learned That graphql. actually this annotations specular decorate us which come with a polar graphql or actually this last JS bandage to it and type OEM I'm share somehow similar decorators if we seen on this entities for example, right? Having this base got written with API can be extended very easily so that we can't focus more on the business parts of our API. You have the flexibility to add? Your own query methods and you're on mutations if this what what public objects share the most commonalities are not sufficient for this very particular entity type. Let's just stay very easy to extend it as you can see. One recommendation. I'd like to give you this to all not to rely on the facilities of Nest chairs or what teams did something different but to pass the entity manager. So this customer this thing which comes with type on itself as the first parameter to each method which gives you very flexibility. To Nest different service method costs for example within a service a uses methods of service baby always pay passing and entity manager. Right and deciding on the most top on the topmost level if it's a regular entity manager or transactional entity manager upon instance. The laws are us to simplify our implementation while dealing with type 1 you can throw exceptions. Everywhere you'd like which roads you will transaction. Prospect your transaction and harvest operations you already done based off entities of obviously from a perspective of the front and application. The most important or crucial thing to do is to understand that we have we're dealing with different instances of Apollo clients. We have different possibilities to rendering 500 front and the web client itself. So web browser. or using server-side rendering on demand or static site Ranger rendering what we haven't seen so far in this Workshop. and and using this typical Use Query and use mid-mutation hooks. There's only possible if you choose. to do it and by web browser if you rely on methods like like shown here, for example Get server side props, for example, you have to create on the server and you apologize. Both queries you execute on the server are not. trackable here inside in the front end Alright, so you have to find another way to do so. right Collective Keys is one of anywhere. I used very operation.
165 min
04 Jul, 2022

Watch more workshops on topic

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