Superfilter AI
Course Description
Design and build APIs from the ground up in Node.js! Use Express to handle routes and create your REST API. You'll read and update from a Postgres database using Prisma and TypeScript. Then add authentication to lock down your API with JWTs. Finally, learn how to deploy your API for the world to see!
This course and others like it are available as part of our Frontend Masters video subscription.
Preview
CloseWhat They're Saying
Just finished the, "API Design in Node.js, v4" course at Frontend Masters. It has been a valuable one. I learned API development with Express.js, TypeScript, Prisma, and Postgres in Node.js.
![Salman Sajid](https://senjaio.b-cdn.net/public/media/63jUmQbnTbvaedrsjo945QPv.jpeg)
Salman Sajid
Consultant Development @ Systems Limited | Vue.js, React.js, Next.js, Typescript
I've just been offered my first role. I can now call myself a "software developer", and Frontend Masters has been a huge part of that. Particularly Scott Moss' API design course made me impress massively in my tech test, and pretty much got me the job. thanks so much to everyone at frontend masters for everything you do ❤️
![Harry](https://senjaio.b-cdn.net/public/media/30a77902-0706-46f9-92e1-c69a32f38dd4_73a0f8bf-db58-4331-9ea0-c126e391b645_default_profile.png)
Harry
Harry
Just now completed the API Design in Node.js, V4 course by Scott Moss on Frontend Masters. Wanna appreciate how good this course actually is and absolutely love the way Scott teaches and explains every single thing. Great course. Highly recommended.
![sky](https://senjaio.b-cdn.net/public/media/9db3bd33-b023-4f03-ac96-76a793447931_9484318b-663c-4058-8af5-f056dfb0ba43_default_profile.png)
sky
gora_badan
Course Details
Published: November 3, 2022
Learning Paths
Learn Straight from the Experts Who Shape the Modern Web
Your Path to Senior Developer and Beyond
- 200+ In-depth courses
- 18 Learning Paths
- Industry Leading Experts
- Live Interactive Workshops
Table of Contents
Introduction
Section Duration: 8 minutes
- Scott Moss introduces the course and walks through the course website. The API project will be built from scratch and the final code can be found in the GitHub repo linked below.
- Scott walks through the tools and technologies used throughout the course. The application will be a product change log API and it will be built with Node.js, Express, Prisma, PostgreSQL, and hosted on Render.com
API Basics in Node.js
Section Duration: 37 minutes
- Scott creates a basic HTTP server using the built-in http Node module. As requests are made to the server, conditional logic determines how the server should respond.
- Scott examines the request and response objects passed to the createServer callback by the http module. Since the request is being handled by the server, no XHR request will appear in the browser. Server-side JavaScript executes in the Node runtime on the server and not in the browser.
- Scott explains the different components of an API including HTTP methods, route handlers, and how IP addresses and ports work. Most of the work of an API happens inside the route handler. These handlers can contain logic for determining how to handle requests, authentication, and limit the number of requests to protect the server.
- Scott refactors the code to use Express instead of the built-in http module. Express is installed with NPM and provides helper methods for defining routes. Depending on the functionality of the API, route handlers can return anything from basic text or JSON, to HTML files.
Prisma
Section Duration: 46 minutes
- Scott introduces ORMs, or Object Relational Mappers. ORMs provide an API for conducting database operations and eliminate the need to write SQL statements inside the application. A question about using JSON in Postgres vs. Mongo is also answered in this lesson.
- Scott explains how Prisma, a database-agnostic ORM, will be used in the application. A PostgreSQL database is created on Render.com. Prisma communicates between the application and Render.com using the external database URL located in the Render.com connection settings.
- Scott installs Prisma and runs the CLI tool to generate the required files for the project. The prisma.schema file contains all the schemas for the data models. The database connection string is added to the .env file.
- Scott creates a schema for the User model. Each user has an id, username, password, and a createdAt field. The id field uses a UUID, a unique string that can be generated by Prisma when a user is created.
- Scott creates the schema for the Product model. A relationship between the Product and User models is established using the Prisma @relation attribute.
- Scott finishes the last two models, Update and UpdatePoint. Relationships are established between the two models. A question about how Prisma supports multiple database platforms is also answered in this lesson.
- Scott runs a migration that syncs the database structure with the Prisma schema. A migrations directory is also created which stores every executed migration. The benefit of having migration files is the ability to track them with source control and ensure every developer is aware of changes made to the database.
Routes & Middleware
Section Duration: 45 minutes
- Scott explains the CRUD operations Create, Read, Update, and Delete. The routes required to execute these operations are created for the Product, Update, and UpdatePoint models. A question about GRPC vs REST is also answered in this lesson.
- Scott mounts the router in the main application and configures it to be used under the "/api" parent route. This architecture makes the application more modular because the business logic for different areas of the application can be defined in separate routers.
- Scott demonstrates using the VSCode extension Thunder Client to test API endpoints. An endpoint needs to return something. Otherwise, the request will hang. With HTTP, the connection with the server is closed once something is returned.
- Scott introduces the concept of middleware and installs Morgan, a logging middleware for Express. Middleware is a function that can be called for any request or only specific routes. The middleware function calls a next() method when it's complete so the request can finish being processed by the server.
- Scott creates a custom middleware that adds a property to the request object. This property is now available to any subsequent middleware and the route handler.
Authentication
Section Duration: 1 hour, 2 minutes
- Scott introduces JSON web tokens or JWTs. The purpose of a JWT is to help identify an authenticated user on the server. The JWT is created by combining the user's ID and username with a stored secret. This creates a deterministic string to identify the user.
- Scott begins implementing a middleware to protect the API routes. The middleware first checks to see if a bearer token is present. If not, it returns and 401 not authorized error.
- Scott adds code to validate the JWT token. The validation logic ensures the token is well-formed. If not, an error is thrown, and the server again issues a 401 unauthorized request. A question about API rate limiting is also addressed in this lesson.
- Scott reviews how authorization headers enforce authentication rules on a server.
- Scott creates functions for comparing and hashing passwords. The hash function takes the user-submitted password, combines it with a salt, and returns a hashed password. The compare function will look at a plaintext password and determine if it matches a hashed version.
- Scott implements the createNewUser function, which hashes the password and creates and new user record in the database for that username and hash combination. The function also creates a JWT and returns the token.
- Scott implements the signin function which will search the database for a user with the submitted username and compare the submitted password with the hashed password for that user.
- Scott adds the routes for creating a user and signing in a user. Both routes result in a JWT being returned if the request is completed successfully. The JWT can then be passed as a bearer token to the protected API routes.
Route & Error Handlers
Section Duration: 2 hours, 26 minutes
- Scott explains why validating user input is important. There are many third-party libraries specializing in input validation. The express-validator module will be used in this application.
- Scott adds the express-validator module to the API and uses it as middleware to check the existence of the name property on the body during a product update.
- Students are instructed to add validation to the remaining product, update, and updatepoint PUT/POST routes.
- Scott begins creating route handlers for the products table. One route handler returns all the user's products. The other returns a single product based on the ID passed to the route.
- Scott codes the create and update product handlers. Both handlers will not only send a product name to Prisma but also the current user's ID to ensure the product that's created/updated belongs to the user.
- Scott adds the product route handlers to the router and tests the application with Thunder Client.
- Students are instructed to create route handlers for the Update and UpdatePoint routes. This lesson includes the solution to the getUpdate and getOneUpdate handlers.
- Scott continues the solution for the Update Handlers exercise. This lesson includes the solution to the createUpdate, updateUpdate, and DeleteUpdate route handlers.
- Scott uses Thunder Client to test and debug all the route handlers in the application. Once a user is authenticated, a product is created along with updates for the product.
- Scott demonstrates how errors cause a Node server to shut down. Express has built-in error handling, however, the default behavior is to output the error message and stack trace. Creating error-handling middleware allows the application to respond differently depending on the error thrown.
- Scott uses the next function to handle an async error. Calling the next function with the error as a parameter sends the error to the next middleware and allows it to be handled like a synchronous error.
- Students are instructed to add error handling to all the API route handlers in the application.
- Scott explains how errors can be handled outside of Express using the process.on API. Similar to using addEventListener, the "on" method has named events like uncaughtException and unhandledRejection which will trigger when certain errors are thrown.
Config, Performance, & Testing
Section Duration: 53 minutes
- Scott introduces environment variables. The NODE_ENV variable lets the application and any other package know the environment. This could be development, testing, production, or any other string. Using custom environment variables for database URIs or secrets allows confidential information to be injected into the application based on the environment.
- Scott creates configuration files for each environment and uses the lodash.merge module to merge custom environment variables into a single configuration object. This architecture allows a default configuration to be created, and for each environment, a customization for a specific environment can override the default.
- Scott explains the difference between blocking and nonblocking code. Whenever possible, developers should use asynchronous APIs because they are nonblocking and more performant for the server when executing multiple requests.
- Scott describes unit tests as testing individual pieces of logic independently. In order for unit tests to be effective, the code should be written in a testable way. For example, function arguments are easier to test than closure variables.
- Scott creates a __tests__ directory and writes a unit test. The describe block is a wrapper around one or more tests. The "it" method contains a statement about what outcome is expected for the individual test.
- Scott demonstrates how integration tests can be used to test an entire route's functionality. The supertest module provides methods for building requests and validating the result of those requests.
- Scott uses the supertest module to write an integration test for the createNewUser route handler. A mock object is sent along with the request with the username and password. The importance of using a testing database is also discussed in this lesson.
Deployment
Section Duration: 18 minutes
- Scott prepares the application for deployment. A build script is created to build the TypeScript files into JavaScript files.
- Scott deploys the application to Render.com. When the code is committed to GitHub, Render.com will pull in the latest version of the code and redeploy it. Environment variables are also configured in the Render.com web service wizard.
Wrapping Up
Section Duration: 5 minutes
- Scott wraps up the course by sharing some final tips for API design and answering questions on recommended API frameworks.
Learn Straight from the Experts Who Shape the Modern Web
- In-depth Courses
- Industry Leading Experts
- Learning Paths
- Live Interactive Workshops