Web APIs with Sails

Rate this content
Bookmark

The "Web APIs with Sails" workshop focuses on creating Node.js web APIs with the Sails framework.

The workshop begins with a beginner's introduction to the Sails framework, we touch on getting started with Sails, installing Sails in your machine, then touch on Sails framework philosophy, concepts, and features.

We continue with the hands-on building of a Web API in Sails from Scratch and test the endpoints with Postman. We round up writing tests for the endpoints, setting up a GitHub action to run our tests when we push to GitHub then deploy our Web API to Heroku cloud.


Prerequisites:

A good understanding of JavaScript and Node.js fundamentals. I prefer to use VS Code for code editing but you can use and editor you want. I expect a preinstall of Node.js and NPM

118 min
02 Aug, 2021

Video Summary and Transcription

This workshop introduces the Sales framework for building web APIs with Node.js. Sales provides a clear structure for codebases and includes building blocks for real-time functionality. It is used by companies like Microsoft and Amazon. The workshop covers topics such as building endpoints, creating models, handling user authentication, and creating and retrieving suites. The workshop concludes with next steps and resources for further learning.

1. Introduction to Sales Framework

Short description:

This workshop is about building web APIs with sales, an MVC framework for Node.js based on Express. It was designed to emulate Ruby on Rails and comes with batteries for building modern applications. Sales improves the day-to-day experience of server-side development and helps build efficient apps with less risk. It allows anyone with basic backend knowledge to quickly get up and running. The benefits of sales include the ability to build practical, production-ready Node.js applications in a matter of weeks, a clear structure for the codebase, and a series of building blocks including real-time functionality with WebSockets.

Let's get started. Let's get started. And yeah, so we're talking about sales. So this workshop is about building web APIs with sales, and I'm going to be your instructor. So it's gonna be an introductory. Yeah. It's going to be an introduction course, workshop, so and.

Okay, so I do hear that they have some noise in the background. So all the windows are closed. So if there's a noise really that jarring or is this like okay, we could work with it. Just leave the yes or no. Okay. All right, thanks, thanks guys. Thank you. Now let's get to it. So like I said, it's going to be an introductory sales course or workshop rather. So a little bit about me, my name is Kelvin M'Hirishone. I'm the founder and the CEO of the Salesforce company where we are building Salesforce. Salesforce is a platform, a resource platform for the sales framework. And I'm also a software engineer and consultant on Node.js. I write technical articles for Smashing, LogRocket and some other, and also on my websites as well as the Salesforce blog.

So, sales it's a framework I really love, in the sense that I had the pain when I started working with Node.js, the pain was if I was going to use Express, I would need to assemble all my dependencies myself and research a lot about packages that would work well together. So, if I need an URL, I'm gonna grab it. And so, there wasn't really no convention. So, I did quite a lot of research to find something that looks like Laravel or Rails. So, Rails is like the MVC framework for Ruby and the same thing for Laravel for PHP. So, I was on that search until I found Sales and it was love. So, what is Sales? So, Sales is an MVC framework. So, MVC means Model View Controller. So, it's a popular architecture for building application. So, Sales is an MVC framework for Node.js and it sits on top of Express. So, what that means is Sales is based on Express. So, if you've used Express before, you would find Sales pretty familiar. But with a whole lot of layers and make things easy and much more elegant than Vanilla Express. So, it was designed to emulate Ruby on Rails. So, the maker of Sales, Mike McNeil, really got a lot of inspiration from Ruby on Rails. And Sales was based on it quite a lot. So, from the get-go, Sales was made to build modern apps. So, the features and out of the box, it comes with batteries that allow you to build modern applications like data-driven APIs, which we'll be doing today, and following the service-oriented architecture.

The sales philosophy. The sales philosophy. One thing I like about the tech I use is, if you think about the well-being of the developers, and Sales got that. So, this is, the sales philosophy have three things, and which is, number one, to improve day-to-day experience of server-side development. Like, it says that if you want to develop server-side app in Node.js, use Sales, because we have thought about how to make Node.js server-side development less painful. And, it also helps you build apps that are efficient, with less risk. Okay, so, during applications, you have to account for securities, and a whole lot of set-up to make sure your app works where I can scale. Sales have got that thought out, and it has added it into its core, from the get-go. So, what sales is all about, again? Lastly, is that anyone who can understand basics, backend, operation-like requests, response could easily pick up sales and get up and running like, almost immediately, in minutes. Which you would see, as we'd get to building. Because this is gonna be a hands-on workshop. So, what are the benefits of sales? Like, what do you like, gain, if I say, okay, let's, let me pick sales as my MVC framework of choice. So, number one, you'll be able to build practical, production-ready Node.js applications. Like, in a matter of weeks, not months. So, sales has the features and the conventions that allow you to be more efficient in building web applications or web APIs on Node.js. So, it makes building complex applications easy. In terms of setup, management, environment, and all. It also has the, it also, in its core, has clean code architecture in it. In the sense that the way things are separated, the separation of concerns, and everything, so it's gearing you towards writing clean code, which, we know, makes our code base maintainable and also easily scalable. So, if we add more teams to it, sales code base, and you wouldn't really need to think much about how they're going to add complexity, because the framework allows that to scale teams easily. So, it makes for a clear structure. So, when you have a sales app, you have a clear structure. So, everyone that comes to that code base would know where every files are, how to edit them, what they do. So, it's all clear to everyone. So, this is good for companies who have a lot of logistic applications. So, different developers could come over time and they could see and meet the same codebase and know how the conversion works. Which makes them ship things faster. So, Sales gives you a series of building blocks. So, by default, Sales comes with real-time functionality with WebSockets. So, if you plan on building real-time applications like chat applications, online games or in-app notifications. So, anything that has to do with real-time, Sales comes with that, like by default.

2. SAILS.js Framework

Short description:

Sales is being used by companies like Microsoft, Amazon, Paystack, and Postman. It can be used to build REST APIs, real-time Shadow applications and games, and full-spec MVC apps. Any service or application that can be built with PHP, Ruby on Rails, or Express can also be built with SAILS. If there are no questions, let's get started.

Which is really amazing for me. So, Sales is not, it's a really old framework, so to speak. In the wild, Sales is being used by a lot of companies like Microsoft, Amazon, Paystack and Postman. So, this company uses Sales and Paystack and Postman are one story I always look out to, how they have been able to scale Sales to millions of users. And that's a lot of inspiration for me.

So, what can I do with Sales, again? REST APIs. So, one of the web APIs on Node.js. Sales could help you build that, which you would see in this workshop. Also, build real-time Shadow applications and games. You could use full-spec MVC apps, with front-end and back-end, like an e-commerce website. So, basically, any service and applications you think of that you could build with anything like PHP or Ruby on Rails, or Express, you could also build with SAILS.

Okay, so now we've got introduced to SAILS. Do I have any questions before I like continue? So, if there's a question you could add it to the chat, then I could answer that before we'll go into SAILS in action. So, any questions? Okay. So yeah. So let's get started if there are no questions.

3. Building a Twitter Clone with Sales

Short description:

Sales is a Node.js MVC framework that allows JavaScript developers to build web apps quickly compared to Express. It provides a convention-based approach and intuitive building blocks. To get started, install the CLCLI using npm, and then run 'sales-v' to see the current version. You can create a new sales project using 'sales new' and choose between an empty web app or a full-blown MVC app. We'll be building a Twitter clone called Sweeter, focusing on web APIs. The functionalities we'll be building include Join Twitter and Login to Twitter endpoints, creating, viewing, updating, and deleting tweets. We'll also cover deployment to Heroku and endpoint testing for sales.

Okay. Yes. Yes. So when I said help you to have faster in weeks, yes, compared to, so we are in the Node.js ecosystem, right? So compared to Express, so if you are a JavaScript developer and you want to build web apps quickly compared to Express, it's quicker and faster in the sense that the convention, pretty intuitive really, and the building blocks it gives makes it so, okay, so I hope we all have a laptops and we have NPM and Node installed because I would really like this to be an immersive collaboration with you guys as we build. So we're gonna build together, okay? So and I'm also gonna give tasks which I will come back to. So who's up for that? The building, are we all in? We're gonna build the workshop, build our mini web API together, so if you have thumbs up or yes, perfect. Okay, so the very first thing, we are going to have to install the CLCLI so a quick npm install that G, sales will install the CLCLI, which is gonna really help speed up your experience using sales. So once you installed the CLI, you should be able to run sales-v, then you see the current version of sales, so let's run that, let's install sales and send me yes or thumbs up when you do. I think you could do that, I haven't really tried that person, but it should work as a dev dependency, so to speak. Yeah, I think you could do. But you might have a little bit of trouble, though. I'm not so sure, but try it out. Try it out. Or perhaps we could do npx sales new. Yeah, I think. But I'm not so sure. But you could try that and tell me how it goes for you. Okay, so while we're doing that, after you're done, to create a sales, a brand new sales project, you could run sales new then the name of the app. So you're going to direct your facility and run sales new then the name of the app. And sales is going to scan for brand new sales project, but it's going to ask you if you want an empty web app or a full-blown MVC app. So sales have a default app, we use is called Caviar. So it's like a full app with authentication, email verification and everything in it. But we won't be using that because we're interested in building web APIs with sales. So not really touching the front end. So that take us to Twitter. Okay, so the project we're building today is called Twitter. So it's like Twitter, but Sweeter. So I was thinking of projects to come up with and I just thought about Sweeter. So why not? So we're gonna be building a Twitter clone with the basic functionality of Twitter called Sweeter and to do that, you could run sales new Sweeter, that's that's no front end. So sales is... Gives you this flag, to scaffold a new application, which is still ought to be a web API. Okay, so it's gonna scaffold the new application still ought to be a web API. And if you've done that, let me know when you've done that. So I have mine already and we'll soon be switching over to my coding view, where we get to code these features and see how sales helps us build faster. So... Okay. Okay, so who has sales up and running? Should I get the, like a yes, thumbs up. Ah, okay. I got one. Anyone else still running sales? Awesome, thank you, Riu. I hope I got that right. So I would... Okay, so let's see the functionalities we'll be building, interested in creating right now. So what we'll build, it would have a course in Twitter like I said. And we'll be able to have a Join Twitter endpoints, Login to Twitter endpoints, create sweets, View all sweets, View single sweets, Update sweets. So sweets are tweets, but Twitter. So we'll also have an input to Delete Sweets. Then, I would give some tasks which we'll try out together. Then finally, we'll look at deploying to Heroku. Good. So if we do have some more time, we'll look at writing endpoint tests for sales or maybe the basic setup. All right, are we good to build in the app? The Web API? We're good? Thumbs up? Okay. So are there any other questions before we go and do them? All right. So let's build.

Okay, so I am. I'm going to probably stop sharing right now so that I could. Okay. I'm going to switch to like a more, to my code for you. Okay. So I'm gonna share. Okay. Can we see my terminal? Okay, perfect. Is the font big enough for you or should I make it a little bit bigger? Okay. Okay, perfect. Okay, thank you for your response. Okay, perfect. Okay, bigger. All right, I will make it bigger Alex. So tell me if this is good. Is it? Yeah, perfect, all right.

4. Building Endpoints and File Structure

Short description:

To start building our endpoints, let's examine the file structure of a Sales app. The API folder contains controllers where actions are defined. The actions can be organized as folders and files, making it more manageable. The help folder allows code reuse and can scaffold helpers, actions, models, and policies. Configuration settings are stored in the config directory, including data stores, models, and policies. The entry points for the application, called custom routes, are defined in the routes.js file. We will begin by building the root endpoints, mapping the '/' route to the 'home/index' action. A VS Code plugin called sailboat can assist in generating actions. Let's delete the existing 'home' action and use 'sales generate action' to create a 'home/index' action.

So I use the sales news Twitter command that I moved from them like you all did. And it's for this for me. So this is like a brand new sales app. There's nothing inside. So it's just brand new. Okay, and if you want to start the sales server, you could just run sales list. Okay, so we're gonna run sales list right now. Yeah, and you could see sales server we're running at the port 1337. Okay, and if we do call, if I do call local host, if I can type 1337. Yeah, you're gonna see not found because we don't have any endpoints yet. So we're gonna open up our project in VS code. Okay, in VS code. So I'm gonna open it up in VS code. Hope you can see my VS code window. And the very first thing we're gonna look at before we start building our endpoints is the sales file structure, folder structure, so to speak.

So by default, a brand new Sales app or an app is gonna have three or two root level folders. The API and the config. They are more if you're like a web, a full-blown web app structure, but we are in a web API, so we just have our API and our config. So 70% of the time you're gonna spend working on your API. So in the API you have your controllers. So inside of the controllers folder you define actions. Okay. So you could have like all your, so in sales we have this convention where you could have all your controllers be represented as folders while the actions could be files inside those folders. Okay. So in that way we tend to separate the action making them linear. So if you want to check at one action you could just go to that action file itself as opposed to having all the actions on one controller file. So I pretty like this, it makes it cleaner and makes it manageable for me. Then going forward we have the help. So help us in sales a mechanism that allows you to reuse code. So anytime you want to do code usability you need a helper for that. So the sales CI can help you scaffold the helper. Sales CI can help you scaffold actions as well as models and policies for access control. So if you want to guard some end points for like, okay, only a logged in user could create tweets for example, I'm gonna use policies for that. I hope that makes sense so far. Okay, in the config directory, any configuration you need for your app right, goes in here. So we have a bunch of configurations. We have for the data stores, where you can set up your database. We have models, global model settings goes in here. Which you could see. You should could see. Okay, then so inside here you get to see your global model settings. We also have policies. So the way we defined policies in Cells-Vida is you get to map actions to the policy that's going to control it. Okay, so we look at building policies in the bits then our apps. So this is like the entry points for your application. So this is where you define what routes your application will expose. So we call them custom routes in cells. Okay, so we have this session settings where you can set your session. If you're going to use session based authentication. We have for circuits, for web circuits, configuration which you could open. If you spun up the cells application you could also see these as I talk about them. Okay, so that's like the brief overview of how cells structures the folders and the projects. Any questions on the structure? Do we have like a thumbs up or something? No. Okay, so are we good to go to start building out the APIs? Okay, good. All right, so that's good. So, we're gonna start off by building the home, the roots end points, okay? So, now if I go to route zero there's nothing here, so the way we define routes and sales is using key value pairs. Here the key is the route and the value is the action that's gonna be handling the route. So, if we want a get routes, it gets request to the root routes or the root end points, want to map it to an action called home slash index. So, it's inside a home controller and the index action will be handling these requests. So, whenever someone requests to the route of our Web API, index is going to handle that. I don't know if that makes sense. And you could see I have a little bit of underline here which I could click on. So, this is a VS Code plugin, extension called sailboat. So, if you want that, you could just go to the VS Code marketplace. If you're on VS Code, and you could just install it and get that functionality out of the box. So, I think while testing I made this home. Actually, so I'm going to delete it now. So, I could show you how you could scaffold actions with sales. So, to do that we're going to say sales generate action and home slash index. So, sales will make a home folder for us inside the controllers folder and create an index action.

5. Building Endpoints and Models

Short description:

To set up an endpoint and handle requests, we can use the home index action. This action is empty scaffolding that can be customized. In this action, we define inputs, which specify the expected request parameters and allow for validations. We also define exits, which determine the response to the action. For this action, we only need one exit. We can return exit.success and pass in an object to automatically send JSON as the response. By saving the file and restarting the sales server, we can test the endpoint. Remember to save your files to avoid errors. With just a few lines of code, we have successfully set up an endpoint and handled the request. Now, let's move on to building the join endpoints. To do this, we need to define a model for the user. We can create a new model using the 'sales generate model' command. In the user model, we define the attributes needed to create a new user. We use the waterline ORM to define attributes based on the waterline spec. For example, we can define the name attribute as a required string and the email attribute as a required and unique string.

All right, so if I click enter, sales gonna tell me, yes, so if we generated index.js and some other helpers. So, it's really just going to guide you on how to use it. So, if I go back now, I'd say I get my home index action and if I open it up, it's just empty scaffolding. So, this syntax here, what you see is an actions to format for writing actions. And so, this makes your action readable and anyone can just come to action and see what the action is about. So, inputs, you're gonna add, so if you're expecting the request to have parameters, you define it here and this allow you to add validations. So, in an actions to style of writing action, you have exits. So the exits, it's going to be like, okay, what would be the response to this action? So, you have a default success as is which means everything is good, then we have error exits, like that would be like a start of 500, so if we want to return anything, any other exits or maybe a user try deleting a record that's not there, you could say not found exit. So, that's what we do here. So, for this action, we're gonna need just one exit because we're not going to do much here. This is the whole map. So, I'm just gonna say that so, our end point is up. So, I'm just gonna say the description. So, successfully reached both endpoints. Okay. Then I'm gonna pass the exit here. And since I won't be using no input, so we don't have to worry about that. So, here we go. Okay, so I could just return exit.success. And I could pass in an object. So, the way Stales work is if you pass in an object, it would automatically knows to send JSON as the response. So I'm just gonna say you've reached the SweetApp, we are like sweeter, but sweeter. Get the idea, okay. So with that done, so I could save this now. So if I save this now, and if I go to restart my sales server, and I use call. Pollocoboost137, okay, let me, I think. Still should have found, did I save? Indeed Home. Okay, let's see the route again. Okay, our windows, okay, that should work. Let's just restart. Okay, Pollocoboost. Okay, yeah, I think, Pollocoboost137. Okay. Okay, yeah, I know why. I didn't save this file. I didn't save that file. So I will restart. I think it should work now. Yes. Okay. So always remember to save your file. Word of advice. Learn from me, from my mistakes. Okay, so we could see with just this line of code, we have set up an endpoint and use this action to handle that request. Does anyone have any question on this? You could type it out in the chat. Is there any questions on this now? So, okay, so if there are no questions, let's go on to building. Let's start with the join, the join endpoints. So to build a joint endpoint, we're gonna need to know the data we want our user to log in with. So we're gonna keep things simple. Just gonna need an email, a password, and a name. So just the user's full name will do. All right, so how do we do that in sales? I tell you how we do that. So to do this, instead we're gonna define a model because we're gonna make new record for each new user. So we're gonna quickly do that by running. So we're gonna create a new model. So I'm just gonna shut this down now. I create sales new model and I'm gonna call this user. Okay, sorry. So that will be sales generates model users. Okay, so that will create a new model in our models directory, which we could see here, models user. Okay, so in this model, this is where we define the attributes we're gonna need to make a new instance of a model user. Okay, so with that said, we could do, so the way we would define the attribute, so sales uses an ORM called waterline. So what we're gonna be doing here is defining attributes based on the waterline spec and it's really quite easy to do so. So if you want a name to be in the user model, we'll just put in a name key, then here we're putting some properties, so one of the type should be string and we want it to be required. So that means any time you want to create a new record, we always need a name, okay? Then we'll go for the email. Also, this will be a string. Once it's required, and we also want it to be unique. So no two user can have the same email. To do that with Sails you just have to say unique true. So that will tell waterline to always check that this model is unique every time a new record is being created.

6. Creating a New User with the 'Join' Action

Short description:

Lastly, the password should be a required and encrypted string. The 'join' action is responsible for handling the logic of creating a new user. It validates the input values, such as name and email, ensuring they are of type string. The email validation is handled by Waterline. The action exits with a success status code of 201 and a description indicating the successful creation of a new Twitter user. Additionally, the action checks for duplicate email addresses and responds with a status code of 409 if the email is already in use. In the case of a bad request, such as missing or invalid parameters, a status code of 400 is returned.

So lastly, I'm gonna ask for the password. And we're gonna say that should be string, and it should be required as well. And it should be encrypted. So, it still has a user functionality that allows you to encrypt passwords, or any field for that matter. So if you want to encrypt anything like SSN numbers, you could use encrypt true on that, and sales would encrypt it when the record's been created.

Okay, so I saved that now. Now, I would go over to the terminal. I could use VS Code terminal here, so I don't need to switch too much. And I could say sales generates actions. We wouldn't need an action for creating a new user. So we're gonna say a user folder. And when we say join, record is action join, just join. So to join sweeter, you're gonna create a new. So, I'll close that up. And before I write the action, I'll go to the routes folder or file, and I would add a new post requests to users. So users. So it posts a request to users would create. So we're gonna say user slash join. So once they request submit to users, it's gonna trigger our join action, which is going to. So it's not gonna do anything right now because we've not added anything. So, let's fix that. So I'll go to join, and in here is where we'll write. So the action is like the meetings of stars, right? So it's what's the outside was going to use in interacting with yourself. So, you could, so this is where you spend most time writing your logic in. So in this action, what do we need to do? We need to get the value being passed in. So we define that in imputes. So we're going to say name. So would say we're inspecting a name. So the way it says action walk is you could validate imputes if you choose to. So we're going to say we need the type to be string. So if user brings in anything that is not a string, cells will complain and that also saves you the extra work of having to write custom logic for these things. So cells would validate that for you. And yeah, so we need email. Type to string. And yeah. So then lastly, we need a password. Then the type, is also string as well. So I didn't add validation for the email. Instead what we could do is email true, so that will cause Waterline to validate if the value is an email. So you don't have to check for that yourself. So that removes that of your hand and leave it for Waterline to validate. So what do we need to exit in? So we need to exit with success of course. So when a new record is created, we use this exit. So you could pass in a status code by saying status code. So in HTTP code convention, a 201 is a resource created. So we're gonna use that. And we're gonna pass a description. So anyone within this should know what it is. It's meant to be successfully created new Twitter user. Okay.

So are there any questions so far? At this speed at which I'm going. So just leave a yes, no, have a question leave it in the chat now. Let's take that break to talk on that. Any questions? Are we there? Do we have questions now? Okay. We're good. Any more thumbs up? And I hope you guys are writing as I am. So did you get to experience those as well? Okay, I guess. Okay. All right. So let's go on writing more on this action. So we also need to check for email already in use, right? So when I'm putting an action, I say email reading use. So whenever a user tried to create an account with an email that's ready to use, we gonna like complain, say this email is in use. So to do that we could say status code. So 409 is for like duplication of resource. So that would be like a duplicate website. We wanna copy the 409. I'm gonna tell the, so we're gonna say, email ready in use in Switzer. Try another something like that. Then lastly, for when there's a bad request, like some values were invalid or we're not passing, we're gonna respond with a status code of 400. Yeah, description should be invalid or missing parameters.

7. Creating a New User Endpoint

Short description:

In this part, we discuss the fn function and how to structure inputs for creating a new user resource. We use a try-catch block to handle errors and return appropriate exits. If the email is already in use, we return the 'email already in use' exit. If there are missing or invalid parameters, we return the 'bad request' exit. In case of any other error, we return a 500 status code. Sales uses an in-memory database called sales disk for development purposes. To test the join endpoint, we can use Postman to send a POST request with a name, email, and password.

Okay. Welcome, Augustine. So, with that, we could move onward to the meets. So, so this, the fn function is like what gets you on when he's actually being called. So you could, it takes two arguments. By default, when you scan for in the instance, there are just the imputes, but you could add the exits as an argument to it. So I like the structuring these imputes. So I will just structure it to like this. So I'm expecting the name, the email, the password. So using here, six, the structuring works here. So with that, I could now use what to land to create this resource. So I'm gonna wrap here in a try cache block. So I'm gonna say try. So what I'm gonna do is const new user. I'm gonna say awaits. So the model you make in sales are globally available to you. So I could say use that or create method. So this is available in waterline and I could tell you to create record with name, send email then password. Okay. Then while that is made I'm gonna fetch it so we could return it back to the caller. Okay, then when I fetch it, I will return the success exit. And since we're writing the web API, I could just say success true. Then I return the new user with the user object key. Okay, then in the cache block I'm gonna do a little bit of check. I'm gonna check if the error have code. So it says emits an error of e.unique. You wanna see unique constraint is being validated. And in our action here, the only unique concept we have is the email input. So if that's the case, I'm gonna return the exit of email already in use. I'm gonna say success, force. And I'm gonna say message, this email is already in use, okay. Then I will also do another else if. So if it's like, so we have an error name called usage error. So if it's a usage error, meaning that a valid in-person does not qualify for the consent receipt. So either it's missing, or it's invalid. So I'm gonna say return, exit dot battery request. I'm gonna say, success, force, then message missing or invalid parameters. Yeah, so that should work that, okay. So lastly, if anything is going wrong, then we would just return a 500. A 500, and we say success force fail. Then message should just be the error. So we start sending error to the caller. I would also like to log out the error here. Okay, so this log error. So we just log out the error, okay? So this is everything we need to get the user or setup. And you might ask that I didn't set up a database connection. So sales have this Memory, in-memory DB called sales disk. So sales disk is going to allow you don't worry about a DB when you're developing. So you could just easily create records and it's going to use the in-memory DB. So that's what I use right now, sales disk. So let's test this out. So this is how I gonna use, gonna use Postman. Okay. Okay, so Postman, I think I'm offline. Let's start off with Postman again. Okay. So I already have like 10 plates. I don't know if everyone can see my screen. So I could like, so this join end points, we wanna test it out in the Bodi. Okay. So here, good. Okay, so we could have a name, and just say, Mike McNeil. Then an email should be McNeil at example. Then a password. Let's say, not really secure password. Okay. I don't know if that makes any sense. So we have these up. So what we're going to do now is we're going to quickly spin up the sales server. Okay.

8. Setting Up the Login Endpoint

Short description:

To set up the login endpoint, we will be using session-based login. We define the route for the login endpoint as a POST request to 'users/login' and map it to the 'login' action. The 'login' action requires the email and password as inputs, both of which should be of type string and required. We also define a 'success' exit, which will return a 200 status code by default. No need to define the status code explicitly.

So now when you spin up the sales server, you're gonna have this prompt, right? It's gonna tell you, you have not set a migration strategy. So by default, the sales migration strategy hasn't be set. So when you notice this point, you could just kill the server and you go over to Config on Config and Data Stores, or models rather. In models, first of all, we need to set schema to true so that we will be able to create any record without a schema, which we just made. So I'm gonna set this to true. And also the migration strategy, we're gonna leave to auto. So in auto, sales is gonna try to save you, your records anytime you leave sales or you drop sales. So anytime you start sales, any record you made will be available. So sales would do its best to keep it up for you. So with that all set, we could leave sales again. Okay. So what, okay, I think let me see if I'm missing the quotes. Yeah, I'm missing quotes. Yeah, so let's leave sales again. Okay. And description. Okay. I think that is the missing parameters. So let's see. Okay, I'm missing a lot of quotes. Okay, I guess maybe that should be all the quotes I'm missing, yeah. So if we go head back to the first line and we hit this end point with this value, it should create a new record for us. So let's see. Yeah, so I'll bring this up a bit. So we could see, we have a new record created for us. Cool. But we have a little bit of an issue. So if you see, based on the constraint we sent, if we try this, we're using this again, it's gonna tell this image already in use with four or nine conflict. If we have missing parameters, like maybe the name is not there, it's gonna send missing parameters and we'll handle that using the action that was there. So one thing I noticed, well that the password was being sent back to the user. So we could tell says, okay, we don't want you to send back the password anytime a new record is created, but that's like sensitive data, right? So the way we could do that is go back to the user model. So we'll go back to the user model and in here we could do custom to adjacent function. So what this will do is that anytime sales is creating a new, is going to respond with a new custom to adjacent. So we're gonna say, we found this. So by default, lodash is bundled with sales. So we're gonna tell lodash to omit for these objects and just remove the password from it. So anytime a new instance of this user model is going to be returned to the user, we shouldn't have this password in. So if I start sales and I try creating, so I'm changing the email now, maybe Daria. Daria, okay. And if I run it now, you will see we do not have the password in here. So that's how to omit sensitivity tool. Okay, so we are done with the join end point. So are there any questions before we move on? So if we're good, let's leave it like a thumbs up, yes. If you don't understand anything, you could come with like a no and leave the question you have in the chat. Any questions? Yeah. Okay, so what's, do we have any questions now? Okay, so are you guys writing with me? Are you actively adding this to your editor? Is this working for you as I just did? Okay. Okay, well, the codebase is gonna be made available and I'm gonna give you plenty of time to like catch up. So I would push it off to GitHub and you could get it from there. So sorry, I'm going too fast. All right, so let's move on to the login endpoints. So the login endpoint we would basically, all we need for the login, we're gonna be using session-based login. So still have that built in out of the box. So it's really easy to do something like a token-based login later on, but we're gonna keep it simple. Just use a session-based login for the user. Okay, all right, so let's try that. So first of all, so this will be like your sales workflow. You go to the routes, you define your routes. So to login, it's gonna be a POST request to users slash login, and it's gonna be to the login action, of course, rightly named. Then we're gonna quickly generate it, sales.generateAction.user.login. Okay, so now we generate that, which we can go into. So to login, all we need is the email and the password. Right, to email, should be of type string and it should be required. So we're gonna use sales impute input validation, it says we require. So if this value is not there, sales is gonna complain and this request will not be honored. So the password, the password should also be type string and also required true. Then, so we're gonna have exits now. So we're gonna say success. So by default, the exits will return a 200. So we need the 200 in this case. So there's no need to define status code.

9. Login Endpoint Logic

Short description:

We use the find method in waterline to find the user with the email. If there's no user or the email and password do not match, we return a request with a status code of 400. If everything is okay, we add the user ID to the session and return a success message. We modify the password check to decrypt the password. If there's an error, we log it and return a 500 status code.

So sales will default to 200 exits. So just question. Let's put in loading. So loading s plan. I think that's it. So let's see. Okay. So, you know what, okay. Yeah. So with that said, we're gonna come down here and we're gonna say, as it's I know I always like structure. So I'm gonna declare this. So I'm just gonna structure it to email password. Okay with that destruction, so I wanna grab the try cache block, so we're gonna say, so here we're gonna say const user equals to await user.find, so we're gonna find user with that email, so we're gonna say email, so using shorthand properties, so this maps to this, but using shorthand properties I can just shorthand it to this. Okay? So now I'm gonna check, do some if section, so if there's no user, or user.email, email does not match, email, or user.password, does not much, password. Then we're just going to return our request. I guess we have to specify the way to exit here. Status code of 400. Let's move down here. Open. Logging credentials. Combination will not match record. Okay, something like that. So, if that's the case, we're just going to return that exit, but to keep it readable, I'm just going to do it here. Return exit.passrequest, passrequest, plus a success false. And message, okay. Credentials, not match any record, okay. Okay, so with that done, so if that's not the case, that means we successfully logged in the user we can now add to our session the user ID, which should be a user.id. So it says milk the session available through this.req which is the coins request. And add a session like so. Okay, and finally we're gonna return a success exit. I'm gonna say success equals true. Then just going to return user. Then if any other thing goes wrong, we just log the error. And we'll return exit.error. Success, false, then just message error message. Okay, does that make sense? So, okay. So yes, what we have. So you could see a brief recap. We use the find method in waterline to find the user with the email. But this find method is going to return an array, but we just want to find just one user, right? So there is a find one method. So we're just going to change that to find one. So you're gonna look for just one recorder match, because definitely no two users have the same email, right? We'll be busy on what are structures. So one that is found, so we're gonna check if the user does not exist, that means it's gonna return undefined, or the user email is not equal to the email being passed, or the user, the password is not equal to the password being passed. And one other thing, this check on the password wouldn't quite work because remember we encrypted the password when we saved it, right? So you have to get like the raw, the real string password, we need to modify this to be decrypted. So sales is going to return the value decrypted as opposed to being encrypted. Okay? So with that said, if everything is okay, then we add user ID to the session and we'll return a success message to the user. In our cash block, we just log the error and return 500 was the message. All right, so let's see if this works. Okay. All right, so let's see if this works. So I'm gonna re-lift sales, sales lift. Okay. And if I go to... Come back here, you see we already have the login. Okay. And so what user do we have in our database? Okay. I think we have Daria, right? We have Daria already. And to see that this really works, like the record we created is really the Kudu sales console. So sales have a console. I think I will need to stop this. So if I do sales console, and I do user.find.log. Okay. So I have created like a bunch of users. Perhaps I could just like... Okay, but you see the last user we need, right? Daria, to be added, but I think I want like a fresh... So I could easily drop all records being created by running sales.leave –drop. Yeah, so that's like there we did all the users. So I could just go back and create the user we created before. Yeah, so that will create it as a new one user. And if I come now to the sales console, user defined.

10. Logging in and Persisting Sessions

Short description:

We're going to run sales.leave now and see the user has been logged in and a session has been created for that user. If you shut down sales and restart it, you'll need to log in again. To persist the session, you can tell sales to use Redis by running sales.leaf --"redis". Now, with the session, you can make authenticated requests without logging in every time.

We're just going to bring back all users and you're going to see Daria is there as a user. Okay, all right, so that just explains that it's there. So you could use that to debug sales. So we're going to run sales.leave now. Okay, sales.leave now and we are going to use these values. And, so maybe again, point of time, you could see there. I'm going in. So we could, okay. So if the record is made, we should get, okay, user defined one. Okay, yeah. Now you're going to jump into this, now this error is VS code now. So VS code imported. If you check, it's imported like the user model. So I have a snippet which I would share that will disable that for you. Start auto-import of VS code. So, if we will start the server now, start that auto-import. And, we try it again. Yeah. We see the user has been logged in and a session has been created for that user. Okay, so now one thing with the sales development session is that anytime you close the, you shut down sales and restart sales, you're gonna have to like, get the session back again by logging in. So one fix for that is to if you have Redis installed locally, you could just tell sales to use Redis by running sales.leaf --"redis". So that will like persist your session. So even if you restart sales, your session is still gonna be there. All right, so now we have the logging in. Since we are using a session, I would be mostly, anytime I shut down sales, I will be like using this auth to like having like a login user here in the auth. So that added an example, so I'm gonna like, yeah, so, so I'm gonna like use it. So I want to tell Postman to reach the authentication credentials from the parent, which this request is in. So that way, I don't need to log in anytime. I want to make like an authenticated request, okay? Which we're gonna get to really fast as we create suites. So I can just add that now. So yeah. Okay. Let's see that. Okay, that works. Yeah, that works.

11. Creating Suites and Setting Up Routes

Short description:

To create suites in sales, we need to define a suite model with a text attribute. We also need to associate suites with the user who created them using a series association. The route for creating a suite will be a POST request to 'sweets' and will call the 'create' action. While the speaker checks something, the audience is asked to provide the route definition in routes.js. The speaker will return with the answer later.

So any questions before we go to creating suites? Yes. Are there any questions you could ask? Any chance? Any questions? Let's leave like a thumbs up or something. Okay, good. So now let's create suites. Suites, rather. So I'm gonna leave you guys out to like try it. So could we tell me how we're gonna, using this knowledge you have about how sales work, how we define routes, set up models, how are we gonna get our suites? Okay, so we will leave that in the chat. So how do we get the suites? So like we need an endpoint for a, an authenticated user to create a suite. Any answers? Are we there? Aha, middle ways, yes, you're right, we should, middle ways. So we have that concept. We have that concept in sales, but we don't call them middle ways, we call them policies, and you're gonna see that at work right now. So what's the first thing we would need to do? We're gonna need to create a suite model, right? So let's do that. Let's create our suite model. So what, so basically we would need a suite to just have text. So sales generates model suites, okay? Okay. Suites, okay. So in the attribute, all we need is to have it text, type string. So unlike Twitter, we don't have any limits. You can type as long as you want, but it's required anyways. Okay, for now this will work at. Then we need to associate the suites with the user who created it, right? So to do that, we're gonna use a concept called series association. So we're gonna say that author here is going to be from the model user. So we're gonna make a one-to-many association where a user has many suites. Then a suite's come only belongs to one user, right? So it's gonna be a two-way. So we're gonna add that here. And we're also gonna add that in the user mode. We don't really need to add that right now, but we could if you want to. So that was to be complete, let us add that, okay. So in the user model, we're gonna come into association and just say, suites. And when we say it's a collection, right, because the user has many suites, the collection will be from the model suites. So this is called the model identity. So it's a lowercase version of the model we created. And vi is like, what is relating these two models, right? So the vi will be the author, which we've added in the other model. I don't know if that make any sense, to make sure I don't mess with my comments again, I check that out. And also here too, okay? Right, so that's good, right? So the next thing we need to do, which I want you guys to tell me, is to set up the route. So what's will the route be? What will the route and definition be in rags.js? So you could type that out. Yes, Twitter has tweets. Twitter has tweets, yeah. We have tweets, because we're Twitter. So what will the route definition be? Any answers? Yes? Okay, so could you guys give me like a moment? I would... Okay, so like I would need a moment to check something. Like let me plug my laptop. So if I go with that, could you just say yes. Like five minutes to plug my laptop before it dies? Okay, thank you. All right, so while I'm gone, you have an, you should get an answer from me on what the routes definition will be, so could go ahead, okay? Okay, so... Okay. Okay. I'm gonna stop the screen share while I get that. Okay. So we're creating a new tweet, right? So we have... We have our sweets model. Okay. All that's created out for us. So I did add the relationships. So I'll talk about the routes. So let's go add that route, shall we? So in here we're just gonna add, so it's gonna be a POST request. So using REST conversion, we're just gonna do it into sweets. And we're gonna call... Here we're gonna call create, just a simple create action. That's what we're gonna do here. And we're gonna... I'll just queue this again. Okay. Okay, I think I will need. Okay, so... I'm gonna be logging into POST, I might just need to create those stuff all over again. I think we could bring it, so we can get to the point. So we'll do this. And now we're gonna do sales generate. Sales generate action, suite of course.

12. Creating a New Suite Endpoint

Short description:

To create a new suite, we need to use the 'create' action. The text for the suite should be of type string and required. The action will return a status code of 201 and a description indicating the successful creation of a new suite. The user ID of the authenticated user will be associated with the suite. If any errors occur, an appropriate error message will be returned. To protect the route, we'll use a policy called 'Logged In'. This policy checks if the user is authenticated and proceeds if they are. Otherwise, a status code of 403 will be returned. The policy is mapped to all actions inside the suite controller in the config file. Finally, we can test the route by sending a POST request to create a new suite, but since we're not authenticated, we'll receive a 'Not authenticated' error message.

Create. And that will generate that for us. Then we'll go to creates. Yeah. So the create needs the text, of course. The text type should be string. String, right? Yeah. And it should be required. So required should be true. Then we're gonna have, so since it's a create, what we're doing, so we're gonna have a status code of 201. Then we're going to, description, gonna be, suite POSTED successfully. Something like that, okay? Then, we are gonna come down here. You know, I always like to structuring. Then, so I'm gonna structure the text out of this. Okay. And, I'm gonna be, EXITS, just remove all these. And, I'm going to, what are we doing here? So we need the user that's creating the tweet. We need to store the ID, and since we already have it in our session, and this is like an authenticated request, we're gonna assume that that is already saved in their, right? So to do that, we would just put a try-catch block, just to be complete, and sweet, so since it's never changed, awaits, sweet.create, then the text. And the author, which we'll just spread there. With this.tweak. then the break does, this dot break dot session, dot users id. Yes. So that's, we associate that user, to the sweet he, it makes, right? Then, okay, then may that is successful, you just return, exit dot success, and we are just going to do, success true, just for the convection where they have, we will turn to sweets. Okay, we will turn to sweets. And here, we just handle errors, see there's a long error. Then we will now, just return, exit that. Error, if anything goes wrong. Success false, or use sweets false, message. Message. Error that message. Okay, all right. So, if everything, looks good, so we will take it to news feed, but, we need to guard this, right. So I, told you that we do that using policies. So we're going to write a policy. So the policy, is self defining, in here. Define it, in policies, okay, so there's no policy right now, so just create, a new policy is logged in, logged in.JS, so what our policy does is, it exports, a function, would do exports, exports. The application's gonna take in Genesis function. The request will proceed, so like a middleware, you know, it works, so now we're gonna check so if, correct.session.userid, it has a user ID, if it has a user ID, then we will just proceed. So proceed. But if it doesn't, that means user is not indicated, so we'll just do address.status, we'll say it is a 403, not authorized. And we say, import JSON, We say, just filling our information, sourcesPost, message. Not authenticated. Okay, all right. So that's that. So now we have this, we'll go to our config, and inside the policies, so the policies.DSL, we just have to map that. So what I'm gonna do, I'm gonna use a wild card. So I say, for every action inside the suite controller, make sure that they are protected by the Logged In Policy. And that's that. And then we set up authentication already. So we've gathered that action. So the way this works is you've got the action and not the route. Because the action is what is going to serve that route, going to act on that route. So if that is done, and I delete the cells now. So if we go here we just quickly create, we call it folder suite. Okay. And in the folder we're gonna add a new request which should be like the create request to create new suite. It's gonna be a POST request. It's gonna be a POST request. Ah. Okay. So it's gonna be POST request. I'm just gonna change this to POST. So I'll say local 1337. Okay. Then to be Suites, then just suites, right? Suites. Okay, so now if we try to hit this route, now we say text new suite on suite up. So if we could, if we try to hit it, yes, we are not authenticated. So we're gonna get this right. So let me make this a bit, so we wanna get this because we are not authenticated. So perhaps, okay, so we're not authenticated, so we'll get that.

13. Creating and Associating Suites with the Author

Short description:

Let's log in and create a new user. Use the created user as the auth. Make a request to create a new suite. Call the fetch function to get the response. Use Redis to fix the need for logging in every time. Successfully created new suites associated with the author.

So let's add that. Let's log in. So I'm gonna create so this is a base request here, and the request. So you're scrolling the both and this would be a post. So he's gonna go to localhost 1237 and to users slash logging. So let's create a new user. Yeah, I'm just gonna know how to map everything to be presentable, I just create a new user folder and add the join, the join. So remember what we needed for the join? Localhost five or seven, the users just a POST request, here should get that up. Okay, so with that, I will just come to the body, create a new test user, call him Keanu Reeves, email Keanu at example.com and the password will be Keanu. Okay, just very simple. So if I create that, okay, Keanu Reeves is created. So we could use that as the auth. So if we add that as the auth now, we'll say the email, Keanu at example.com example.com We could now add the password Keanu. Okay, so, if I make that request and that's successful, that means, I could now, if I share the authorization, so the reason why this will work is, we're telling it to inherit auth from parent, right? So it will cascade into these folders. So if I come here and I'll say create NEWT, yeah, created, right? So we can see that it's working. So if I come back here, so the reason why we didn't get any response back because I didn't call fetch. So if I go back to create and remember, we have to always call fetch if we want the response back. So if I add the server again and I call and I create, okay, you know we have to, since we're using the local session, we have to relog in. But I told you to use Redis to fix that so you don't have to log in every time. So now we've successfully created new suites and you see we've associated with the author. Good?

14. Retrieving Suites with Authors

Short description:

To show the suites and their authors, we create a new request called 'get suites'. This is a GET request to 'localhost 127/suites'. We generate the 'get suites' action and modify the policies to allow anyone to access it without authentication. In the routes, we define the route for 'get suites' and specify that it is a GET request to 'suites/get suites'. The action returns a success message and retrieves the suites from the database, populating the author association. The suites are sorted by creation date, with the most recent tweet first.

So the client might want to show the suites plus the author of the suites like the way Twitter does. So we're gonna have like another request here called all suites. We'll just say get suites. Get suites. So it's gonna be a GET request to localhost 127 and suites, okay? So this doesn't exist right now. So if we run it, it's gonna say not found. Yeah, so let's write that out. So I'm gonna just quit the server quickly and just say sales generate, sales generates action suites get suites, right? Okay. Then that will generate that for us. And remember, it's gonna be authenticated by default but we don't want that. So we want to like let our users be able to see a suite but they wouldn't be able to see an individual suite. They'll have to login. So we could modify our policies. Our policies now, I say, okay. When this gets suites action is called do not apply the login policy as you normally do. So we'll just say true. So that means this is open. Anybody could just access it. So that's what true means. So this is how to like set different policies on overriding policy. Okay, so that one will go to our routes And in here, we could just do a post or get rather. Okay, suite. Then we do suites, get suites. Suites, okay. All right. So yeah. Now on this. Okay, let's go in here. So we don't have any imputes. All we have is like a success. So mostly it's a success. It's a guest request, so even if there's nothing in the database, it will return like an empty array. So basically we don't really need much here but a description. And see, so, suites retrieved successfully, okay. Then we could just, we don't need this. So we could just face it with an underscore and say exit. And in here is where we add the logic to get suites. So for suites is equals to await suites, dot find. Okay. So find everything. But, I want you to, to populate. So we have this populate method which will, so if you see our association in here, this association, now, you could see it's just the ID. But Salesforce gives me an option to populate the instance itself, like the object, instead of the ID representative. So to do that we'll just say, okay, opulate the author of the suite. And also I want you to sort it, sort by credit address, so that the alias tweet comes first. So this is just how we do it. Then we could, then we could say we turn exit.success. Success.true. Then we just return the suite. Okay. And just this two line, we are done. So if you want to handle for errors, so I don't think we'll run into much errors because our server is not on, our server is not started, but this should basically work out of the blue. Just this two line should get you out of it. So here we're populating the author. So let's see how that goes. Let's see if it really works, like I said, it won't. So we'll come to getSuites, and we'll make that request. And then see, we have our suites and also with the author populated in here. Okay. So that's how you work with associations, right? So now we have that.

15. Adding the GetSuite Route

Short description:

We need to write a getSuite route for the Twitter clone. This will lead us to URI templates in sales and adding dynamic variables. The getSuite route should be authenticated, allowing only logged-in users to see a suite. We can open the getSuite action and define the parameter type as a required integer. We use the suite's ID to find the corresponding suite. If the suite is not found, we return a file not found error. If the suite is found, we return a success exit with the suite details. Finally, we can lift the server and test the getSuite route.

So that's how you work with associations, right? So now we have that. What's the next route we need to write for this Twitter clone? So next we need to like, maybe have a getSuite. So we get that individual suite, getSuite, okay? So we're gonna go over the whole crud. So this one is gonna lead us into talking about URI templates in sales, how to like, add dynamic variables because we're gonna have suites then maybe with the number. Okay. But for now this is shouldn't bring anything, does it? Yeah. So let's write that, okay.

To start the server, we do sales generates, generates suites whatever action suites, so it's getSuites okay. Then we go to the route. So that route wanted to be authenticated, right? So only logged in user could like see a suite. Then, we say, getSuites then to add a partial, we just put a colon and the partial name. So you just be like, suite. Okay, so like this will be replaced. So we will say map it to suite slash get suite, okay. Then with that, we could open up the, the get suite. One of the get suits, give me a moment to turn off this time. So we could open up the get suite. So we are gonna get a get suite now. We would have, the parameter of the past, we could also set it in here, telling still that this is the type of want it to be, so type number, because our ids are numbers, and it should be an integer, because we don't have decimals as an ID right now. So integer should be true, and it should also be required. So do not follow this request. So with that, we could say success. So description, successfully retrieved, a suite, okay? All right, so, I'm gonna follow the structure like I do. And here we'll write... okay. Then we could have... So let's think of it. So we'll need to check if the suite uses, the ID provides leads to a suite, or if it doesn't. So we just need to do const suite, await suite.find one, because it's one suite we're looking for right now. So find, via the ID. So I could do ID, issue then, which is, so I, so it's equivalent to ID wanting them, if that base were using ID. And that should be it. So if not suite, that mean suite was not found, we can return and exit the, the file not found, just say suite not found, and we'll say sources false, message suite not found. Okay, but if it's found, we just have to return exit dot suites, I'm sorry, exit dot success. Okay, success is true, now we return to the suite, and that's that. So, we could lift it now. Okay, what do we have here? Suites, okay, yeah, I think I know why. So, all we do is we just remap it to ID, because so it's already defined. So, can I get that right? I think is it the other way around, like so. Okay, yeah, that's supposed to be, so ID suites, and here we run to pass in. Okay, I think it's the other way around, so we just have to alias it to ID, I guess. Okay, yeah, so the the other way around, I always switch that up. Every time, every time I do switch that up. Okay, so with that, we could come over here, and to get suites. So you have a suite that has an ID of 2, but you have to sign up, because it's hard to log in again. Yeah, so if we're going to get suite now, let's come. Aha! We have the suites, but let's also add the author rights. So let's add the author of that suites and hopefully it's author. Log in again. We just get suite. Hmm. Okay, yeah, that's true. The reason why is the user it doesn't exist anymore. Cause I switched systems. What we could do now is to quickly. So do I not have any empty suites? Just drop this. Then we create the new create a new user. Like new at joint, lut Cambridge joints again, and logging in. We create create a suite. Good. Then we could okay, ID of the suite? Any ID of the suites? Too obvious, very good. Okay. So, I didn't add I knewbros not leave that out. So I didn't add suite not found, let's go to add-access. Code 404 not found. Hmm. So, I believe it's not gonna be found. But let's see the suites we have. Okay, so we have more suites now with ID of three. Okay, so if I do ID three, okay.

16. Updating and Deleting Suites

Short description:

We will add two more endpoints for updating and deleting suites. The update endpoint will be a PATCH request with the suite ID and text as parameters. We will also create more suites to work with. The delete endpoint will be a DELETE request with the suite ID as a parameter. After completing these endpoints, we will share the collection and GitHub repo. Let's quickly implement the update endpoint by generating the 'suite updates' action and defining the route. We will validate the suite ID and text parameters and handle different scenarios such as the suite not found or the user not authorized to update the suite. If everything is fine, we will update the suite and return a success message. Finally, we will add the delete endpoint by defining the route and handling the delete request for the specified suite ID.

ID three. Oh! ID 15. Okay, ID 15, right. The user is three, ID 15. Yeah, so we get our suite back. So, unlike Twitter, we want our suites to, like, we want our user to be able to update the suite, right? So we're gonna do two more endpoints, and we'll call it a wrap. Is that good?

Okay. So let me see. Do we have any questions so far? Are we also working on, as I'm adding them, do we also work on them? Any questions? Let's see what's happening in the chats. Okay, for some reason my noise not working. Okay, so are there any questions? So that's...

Okay, so let's add updates suites. So update suites will clear that request, call update suites. So it's gonna be a patch request. Suites, so a patch request with the suite ID. So before, let me just create more suites, so we'll have a whole set of suites to involve. Okay, and another suite. Another suite. Okay, all right. So you can create as many users, if you have postman on, you can create as many users as you want. Okay, and yeah, so let's do that. So we're gonna do patch and we're gonna do delete, then we'll call it a wrap, I will share the collection with you and also the GitHub repo where you could get it from. So I do know it's getting pretty late over there. Alright, so let's quickly do update. So to do the update, we're gonna come back here, sales generate action, suite updates, suites. Okay, then we're gonna go to the routes, we'll come here and say, okay, we need a patch route. So any patch will be put in the routes. So these, suite, we just say which update suites, okay. And from the suites well here in this stage, so we have a text, definitely, so we need a text, for the suite ID, which is a suite we're passing there, should be a number, it's not like a number, should be a number here. and it should be, required through, and it should be It's the integer. And type string, the string which is, the text you want to leave the sweets with, it should be required as we are not going to give an empty text, required through, and we're gonna have some couple of exits here, first of all we gonna have like, sweets updated, then we gonna have, sweets not found, sorry, case, so it's gonna be status code, 4.0.4, description, sweets not found, and gonna have, not authorized here as well, so what this will be, so if a user is trying to update it, which he does not, he didn't create, when he responds with a false, stop of right, he can't do that, that's criminal, do not update sweets within creates, so when there's a, as you cannot updates sweets, okay? So here, just leave it as ID, I just like being consistent with this one, so I can remove this, so I can leave it as sweets, if you want, so this will also work, so we are sweet. Text, then would have an exit here, and say, sweet to update, but okay, sweet to update, say I'll wait, sweet. updates, okay, first of all let's find the sweet, I'm just trying to sweet sweet update, equals to await sweet.find1, so if it exists, let's find it first, so will leave, now sweet on date, then we return exit.sweet not found, so access before this message, sweet not found, and else if, so if sweet2update.author is not equal to not equal to the date, and exit.break, for session user ID. Then this user will start to use create as a sweep, at the script. So to return exit.notauthorized, success false, message, message, notauthorized, or this action, sort of speak. Then lastly, that means everything is all good. If none of those branches was calling that means everything is all good, they would just return. So, it's, so just updates the switch as before we've done it. So we do false, updated, switch, await, switch dots update one. So we have UpdateOne method. So find it by ID, dot sets or comma seven. It's a passing dot text. Okay. So that's good and then we will have, gonna return, exit dot success, and we'll return success to, then return updateん switch. Okay. Like so, as I said the same here. So this work. So go through switch is declared. We will never use it. Okay. We're mapping to this. Yeah, and that should work. So if we start our server now and we call to all these switches. So we would have a text updated from Ghostman, like so. And yeah, this should complain because we're not loading. Yeah, if we're logging now, and if we check all that, okay, so let's, this is 16, more with ID of 16. Let's update that. So 16, so we'll say update from Ghostman. And yeah, update their flow, oh, type, you can still, so because we're not tweeted, we can update and we will be using fix that type right there. So that's for the update. Lastly, before we wrap this up, since we're way beyond time, we could, the routes to delete sweets, okay. Let's delete that sweet. So we add delete sweets. So it's just gonna be a delete request. So it still supports the delete request and it can be sweets and just the idea of the sweets to delete so they can be keeping everything persistent for the routes. We just paste it. Okay, we could sweets. Delete. Sweets. Sweets.

17. Creating, Updating, and Deleting Suites

Short description:

We generate the 'get suites' action and modify the policies to allow anyone to access it without authentication. The suites are sorted by creation date, with the most recent tweet first. We will add two more endpoints for updating and deleting suites. If everything is fine, we will update the suite and return a success message. Finally, we will add the delete endpoint by defining the route and handling the delete request for the specified suite ID. These workshops tend to give you an introduction to sales and show you what's possible. There are a couple of other endpoints you will want to do, such as likes, unlikes, and commenting on tweets.

Sweets Employees. And we could now sales generate action sweets. Delete sweets. Okay. Delete. So it's gonna be kind of identical to update sweets. Okay, now we know that but we need sweet not found. So we could just copy that. So since we have mechanism to I wouldn't allow to have to copy this all the time. So much to still can get to right now. But the whole idea is to show you what's possible just with sales. So we have within a standard dependency. This is just sales. I wouldn't do with it. So I'm going to don't feel like typing out all this code. okay, perhaps I should. rather, let's just type it in. Don't be lazy, Karen. So that's the code we have we just typed. Sweep ID as we do. So basically, we're gonna take this panned block limits and fairness thing. Go want to rename most of it or so sweeps or dates. So probably the sweep. I think let's just sweep to delete. Sweep.51 Sweet. I did. So if not sweet or delete hasn't done this. Return and it's sweet success. Nice way. Sweet. That was pretty sweet. So the leads more people. Excuse those correct session those user lady. Return water tap rise. Success Good. So we still delete like a record. Await suites or destroy. Okay. We don't have any type 2. This should work. Okay. it says I have to do it myself. Let's jump in. Okay. And now we're going to test it. You know First we have our test something. Okay. I think we took all the fetch minutes. What if you tried to delete that? Same. Cause it's been deleted. I think so. You shouldn't sweep the farm. Yeah. So what do I forget? Like the switch? I do a 15. I forget to switch. Yeah. So it's right now. If you want to get rid of don't have any sweets and to sweets or create as much sweets as we want. Sweeter sweets. Okay. Get sweets. And then, so we have like we have seven in points already and within like an hour or so and based on my technical issue, I was wait. So we'll see how we were able to create this. So at the get go, this is already production ready so to speak so, so there so that's the introduction to sales. These workshops tend to give you, so I'm gonna push this over so you could have access to it. Okay, no points. Okay, then. So I'm gonna push it. So, yeah, so there are a couple of other endpoints you will want to do. So still, today, we'll work on it over on Discord so you could do the endpoint for likes and unlikes and to like the tweets will also comment on my tweets.

18. Conclusion and Next Steps

Short description:

I'll share the repo on my Twitter and make it public. I apologize for the technical issues. We can continue with a quiz and you can join the sales cast Discord community. If you have any questions, feel free to ask. I'll provide the Discord link and share it on GitHub and Twitter. If you need the slides, let me know. If there are no more questions, we can conclude here and continue the discussion on the Git nation Discord.

There we go. Okay. So that's the intro. And I hope we get to see at a basic level what we can accomplish. Yeah, I'm gonna share the repo immediately. So right now is private, but I'll make it public and I'll post it on my Twitter, so you could follow me on Twitter. I'm also gonna post some like yeah, you're welcome. I'm so sorry for the technical issue. I planned a whole lot to share with you guys like the comments, reflexive associations and all that. So but the good news is we could, start to have a quiz. We could go on from here and you could join the sales cast discord and I will be able to guide you to where I appreciate you. If you want to go for all the sales from here, I will share the discord link. I will share the discord link. I think I should be able to share it here. So give me a second for it. Okay, so I will be able to share that. And yeah, so any questions? Any questions at all? So that's the link to join the sales cast community and also from Twitter. So I will add it to the GitHub and I will also tweet it. And also if you want my slides, I could also make that available as well. So if you do not have any question, I could let you guys go now. They will continue this discussion on the Discord, on the Git nation Discord.

Watch more workshops on topic

Node Congress 2023Node Congress 2023
109 min
Node.js Masterclass
Workshop
Have you ever struggled with designing and structuring your Node.js applications? Building applications that are well organised, testable and extendable is not always easy. It can often turn out to be a lot more complicated than you expect it to be. In this live event Matteo will show you how he builds Node.js applications from scratch. You’ll learn how he approaches application design, and the philosophies that he applies to create modular, maintainable and effective applications.

Level: intermediate
Node Congress 2023Node Congress 2023
63 min
0 to Auth in an Hour Using NodeJS SDK
WorkshopFree
Passwordless authentication may seem complex, but it is simple to add it to any app using the right tool.
We will enhance a full-stack JS application (Node.JS backend + React frontend) to authenticate users with OAuth (social login) and One Time Passwords (email), including:- User authentication - Managing user interactions, returning session / refresh JWTs- Session management and validation - Storing the session for subsequent client requests, validating / refreshing sessions
At the end of the workshop, we will also touch on another approach to code authentication using frontend Descope Flows (drag-and-drop workflows), while keeping only session validation in the backend. With this, we will also show how easy it is to enable biometrics and other passwordless authentication methods.
Table of contents- A quick intro to core authentication concepts- Coding- Why passwordless matters
Prerequisites- IDE for your choice- Node 18 or higher
JSNation 2023JSNation 2023
104 min
Build and Deploy a Backend With Fastify & Platformatic
WorkshopFree
Platformatic allows you to rapidly develop GraphQL and REST APIs with minimal effort. The best part is that it also allows you to unleash the full potential of Node.js and Fastify whenever you need to. You can fully customise a Platformatic application by writing your own additional features and plugins. In the workshop, we’ll cover both our Open Source modules and our Cloud offering:- Platformatic OSS (open-source software) — Tools and libraries for rapidly building robust applications with Node.js (https://oss.platformatic.dev/).- Platformatic Cloud (currently in beta) — Our hosting platform that includes features such as preview apps, built-in metrics and integration with your Git flow (https://platformatic.dev/). 
In this workshop you'll learn how to develop APIs with Fastify and deploy them to the Platformatic Cloud.
JSNation Live 2021JSNation Live 2021
156 min
Building a Hyper Fast Web Server with Deno
WorkshopFree
Deno 1.9 introduced a new web server API that takes advantage of Hyper, a fast and correct HTTP implementation for Rust. Using this API instead of the std/http implementation increases performance and provides support for HTTP2. In this workshop, learn how to create a web server utilizing Hyper under the hood and boost the performance for your web apps.
React Summit 2022React Summit 2022
164 min
GraphQL - From Zero to Hero in 3 hours
Workshop
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.
TestJS Summit 2023TestJS Summit 2023
78 min
Mastering Node.js Test Runner
Workshop
Node.js test runner is modern, fast, and doesn't require additional libraries, but understanding and using it well can be tricky. You will learn how to use Node.js test runner to its full potential. We'll show you how it compares to other tools, how to set it up, and how to run your tests effectively. During the workshop, we'll do exercises to help you get comfortable with filtering, using native assertions, running tests in parallel, using CLI, and more. We'll also talk about working with TypeScript, making custom reports, and code coverage.

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

Node Congress 2022Node Congress 2022
26 min
It's a Jungle Out There: What's Really Going on Inside Your Node_Modules Folder
Top Content
Do you know what’s really going on in your node_modules folder? Software supply chain attacks have exploded over the past 12 months and they’re only accelerating in 2022 and beyond. We’ll dive into examples of recent supply chain attacks and what concrete steps you can take to protect your team from this emerging threat.
You can check the slides for Feross' talk here.
Node Congress 2022Node Congress 2022
34 min
Out of the Box Node.js Diagnostics
In the early years of Node.js, diagnostics and debugging were considerable pain points. Modern versions of Node have improved considerably in these areas. Features like async stack traces, heap snapshots, and CPU profiling no longer require third party modules or modifications to application source code. This talk explores the various diagnostic features that have recently been built into Node.
You can check the slides for Colin's talk here. 
JSNation 2023JSNation 2023
22 min
ESM Loaders: Enhancing Module Loading in Node.js
Native ESM support for Node.js was a chance for the Node.js project to release official support for enhancing the module loading experience, to enable use cases such as on the fly transpilation, module stubbing, support for loading modules from HTTP, and monitoring.
While CommonJS has support for all this, it was never officially supported and was done by hacking into the Node.js runtime code. ESM has fixed all this. We will look at the architecture of ESM loading in Node.js, and discuss the loader API that supports enhancing it. We will also look into advanced features such as loader chaining and off thread execution.
JSNation Live 2021JSNation Live 2021
19 min
Multithreaded Logging with Pino
Top Content
Almost every developer thinks that adding one more log line would not decrease the performance of their server... until logging becomes the biggest bottleneck for their systems! We created one of the fastest JSON loggers for Node.js: pino. One of our key decisions was to remove all "transport" to another process (or infrastructure): it reduced both CPU and memory consumption, removing any bottleneck from logging. However, this created friction and lowered the developer experience of using Pino and in-process transports is the most asked feature our user.In the upcoming version 7, we will solve this problem and increase throughput at the same time: we are introducing pino.transport() to start a worker thread that you can use to transfer your logs safely to other destinations, without sacrificing neither performance nor the developer experience.