REST & GraphQL API Design in Node.js, v2 (using Express & MongoDB)
This course has been updated! We now recommend you take the API Design in Node.js, v3 course.
Table of Contents
REST APIs with Express
IntroductionWelcome to the course! Scott's background is in working on Tipe, OneSpeed, Angular and more. Scott gives an introduction to what Node.js is, a platform built on Chrome's V8 engine with it's own modules for HTTP and file I/O. He gives an overview of the popular Node.js frameworks.
Intro to ExpressExpress is the most popular framework for building APIs and is very extensible. There are modules for routing, middleware, and lots of plugins to do whatever you would need for building APIs for REST and GraphQL.
Exercise: Setup ExpressOverview of the files involved in the exercise to bootstrap express.
Solution: Setup ExpressScott codes setting up express and returning a JSON response with a GET request.
Solution Branch WalkthroughScott walks through the solution branch code which contains hot module reloading (HMR). HMR speeds up development by loading your node modules through webpack right after your files are saved.
Routing & Middleware
Routing with ExpressExpress Routing module has many features including pattern matching, multi-router support and support for all HTTP verbs.
Excercise: Express RoutingIn the challenge you'll be creating your own express sub router modules to route different paths to resources in the API.
Solution: Express RoutingScott walks through the solution of importing the sub routers and setting up the routes. He takes the parameter of the route and passes that to the controllers. Scott also gives an overview of REST using HTTP verbs and the tradeoffs of it.
Controllers & RespondingInside controllers you handle incoming requests and send back the response. Scott codes a controller method that works for all the resources as well as handles errors.
Exercise: Controllers & RespondingScott sets up the next exercise for getting the API route tests to pass by implementing the controller methods.
Solution: Controllers & RespondingReview of the solution implimneting the methods to create, update and read the model data based on the routes. Scott also reviews how the route parameter gets passed into the param method in the router.
MiddlewareMiddleware allows you add hooks to run a set of functions before the request is send to the controller. This is great for adding behaviors like authentication and logging to your express API.
Exercise: MiddlewareScott sets up the middleware challenge. Scott get you started JSON parsing with the bodyParser middleware.
Solution: MiddlewareReview of the middleware solution to parse the URL and protect the API with authentication middleware.
Setup Mongo Models with MongooseScott shows how to get up and running with MongoDB by creating Mongo models using schemas with the Mongoose node library.
Exercise: MongoDB ModelsCreate MongoDB models with schemas to pass the tests. Scott covers how to throw custom model data errors and get started with the exercise.
Solution: MongoDB ModelsScott walks through building out the model schemas in Mongoose.
CRUD in the ControllersCreate controller methods to handle each of the CRUD (Create, Read, Updated & Delete) verbs.
Challenge: Querying MongoDBLearn how to query MongoDB. In this exercise you need to code find by ID, find by name, create and update.
Solution: Querying MongoDBLearn how to query MongoDB. Scott shows how to find by ID, find by name, create and update documents and more.
Config & Tests
Dynamic ConfigurationMake your configuration files dynamic by having a base configuration and injecting variables into each environment based on the environment variables.
Exercise: Dynamic ConfigCreate an extendable configuration file based on the development environment.
Solution: Dynamic ConfigChange your configuration: secrets, keys, and URLs based on your environment. Scott also shows how you can create environment files to store your secrets.
Writing TestsHow to code out unit tests using mocha and chai.
GraphQL OverviewAn introduction to GraphQL, a query language for your API that allows the client to describe how they want their data.
GraphQL vs RESTA comparison of REST and GraphQL. GraphQL is typed and is a dynamic single endpoint. With REST you have to predefine the data and endpoints individually
GraphQL SchemasGraphQL APIs use schemas to definte the types, queries and mutations that can be queried on the API endpoint.
Queries and Mutations WalkthroughScott walks through GraphQL queries and mutations using the interactive documentation that comes with GraphQL called "GraphiQL".
Exercise: GraphQL SchemasCreate the type definitions for Song and Playlist.
Solution: GraphQL SchemasScott walks you through how to create the type definitions for Song and Playlist. He also answers questions about using comments in GraphQL and auto-generating schemas.
GraphQL & ExpressGraphQL is seprate from the server and request-response cycle. So you need a server like Express to send and receive the data for your API. Express talks to the Node libraries that impliment GraphQL.
Exercise: GraphQL & ExpressGet started with using the Express Apollo extension to attach GraphQL to the Express server. Scott walks through the setup code.
Solution: GraphQL & ExpressScott walks you through gettings setup with resolving GraphQL requests through the Express Apollo server module.
Resolvers OverviewResolvers allow you to define queries. Resolver methods take four parameters: root value, arguments, context and the AST of the query. You'll most of the time just use arguments and context.
Nested ResolversThe magic graphQL is in being able to nest resolvers and continue to resolve more data into the response as the user requests more data in the GraphQL query. You can avoid resolvers from running altogether if the user doesn't need that data that the resolver provides.
Exercise: ResolversCreate the resolvers for the Song type and Playlist type. Use the User type example for reference.
Solution: ResolversCoding out the Song resolvers and how to handle errors in GraphQL Apollo Server. Scott also shows where nested resolvers are needed.
Mutations OverviewWhen you need to make changes to the data source you can add a mutation. Mutations need their own resolvers.
Mutations WalkthroughScott walks through how to use a mutation from the client in the query and how to impliment that mutation on the server.
Exercise: MutationsImpliment the create, update and remove mutations for Song and Playlist models.
Solution: MutationsWalkthrough of coding the create, update and remove mutations for the Song and Playlist model.
Non ScalarsAny custom type or object in GraphQL is a non scalar. Non scalars have to be resolved to primitive types.
Exercise: Non ScalarsCode nested resolvers for resolving the non scalar type references in your models.
Solution: Non ScalarsScott codes nested resolvers to resolve the non scalar types.
Tracing Nested ResolversDemonstration of logging the resolver methods to show which resolvers are run depending on the query on the client.
AuthenticationProtect your data using authentication on all of your resolvers.
Exercise: TestingIn this challenge you are to write out tests for the GraphQL model mutations and resolvers.
Solution: TestingScott codes out tests for a GraphQL mutation and resolver.
Using REST & GraphQLThere are many different strategies to exposing and using both REST and GraphQL APIs on the same API.
Q&A and Wrap-upScott wraps up with Q&A about GraphQL. Scott says he uses Apollo GraphQL server for everything. He believes Graph APIs will replace REST entirely since it's a much better fit for the types of applications we build today. Follow him on twitter @scotups