Study Notes Node JS
Section 1: Understanding APIs, Express, and Mongoose
Express is a fast, unopinionated, minimalist web framework for Node.js that is used for building web applications and APIs.
Key Points:
- Express allows quick and easy setup of a web server.
- Express is used for building web applications and APIs.
Mongoose is an Object Data Modeling (ODM) library for MongoDB and Node.js.
Key Points:
- Mongoose manages relationships between data.
- Provides schema validation.
- Translates between objects in code and representation of those objects in MongoDB.
Section 2: MVC Architecture
Model-View-Controller (MVC) is a software design pattern commonly used for developing applications that divides the related program logic into three interconnected elements:
- Model: Represents the data and rules governing access to and updates of this data.
- View: Renders the contents of the model. It specifies exactly how the model data should be presented.
- Controller: Handles user input and calls model and view methods accordingly.
Section 3: Latency & Throughput in APIs
Latency is the delay before a transfer of data begins following an instruction for its transfer, whereas Throughput is the amount of data moved successfully from one place to another in a given time period.
Key Points:
- Minimizing latency and maximizing throughput are crucial for ensuring a smooth and fast user experience in terms of APIs.
Section 4: Understanding Authentication
Authentication is the process of verifying the identity of a user by obtaining some sort of credentials and using those credentials to verify the user's identity. The authorization process starts if the credentials are valid.
Section 5: Serving Static Files with express.static
express.static is a built-in middleware function in Express used to serve static files like images, CSS, and JavaScript directly to the client.
Section 6: Testing with Jest and Supertest
Jest is a JavaScript testing framework with a focus on simplicity, and Supertest is a high-level abstraction for testing HTTP, built on top of superagent.
Key Points:
- They can be used together to write tests for your Express APIs.
- Tests can be Manual (user runs test via the UI) or Automated (test scripts are executed that call into the code and compare results to expected values).
- Tests vary in granularity: Unit tests (focuses on individual components, functions or methods), Integration tests (set of components that are collaborating to perform a task), and End-to-end tests (complete application running in an environment that mimics a real-world production environment).
- Tests have different purposes: Functional (Positive - does it work when it is supposed to, Negative - does it fail when it is supposed to), Regression, Smoke, Performance / Load, Usability, Security, Compatibility, Recovery, and User Acceptance Testing (UAT).
RESTful HTTP Methods
| Method | Crud Functionality | DB Action |
|---|---|---|
| GET | read | retrieve data |
| POST | create | add data |
| PUT | update | modify existing data |
| PATCH | update | modify existing data |
| DELETE | delete | delete existing data |
RESTful Routes
| Action | Method | Path | Action |
|---|---|---|---|
| index | GET | /engineers |
Read information about all engineers |
| create | POST | /engineers |
Create a new engineer |
| show | GET | /engineers/1 |
Read information about the engineer whose ID is 1 |
| update | PUT | /engineers/1 |
Update the existing engineer whose ID is 1 with all new content |
| update | PATCH | /engineers/1 |
Update the existing engineer whose ID is 1 with partially new content |
| destroy | DELETE | /engineers/1 |
Delete the existing engineer whose ID is 1 |
Setup For Server Side Rendered (SSR) Basic Restful Full CRUD APP
- Make a directory for the project
- Create a
server.js - Run
npm init -yto initialize a Node project in the directory -
npm install express -
npm install jsx-view-engine method-override mongoose dotenv - Require Express in
server.js:const express = require('express') - Create an instance of an express app:
const app = express() - Make your app listen on a certain port:
app.listen(3000, () => console.log("Running on port 3000!")) - Require all modules and configure all middleware including the view engine
urlencoded, locals, methodOverride, jsx-view-engine, static - Set up
.envand.gitignorein your.envadd yourMONGO_URIand in.gitignoreignore your node_modules and .env file - Set up your models and connect your database
- Set up your controller & router functions/handlers
- Create a
public/folder with acss/subdirectory within it - Create a
styles.cssfile within/public/cssand add your styling - Host your
public/folder:app.use('/assets', express.static('public')) - Include your CSS in the head of your
views/layout.hbsfile:<link rel="stylesheet" href="/assets/css/styles.css" /> - Build your views
Index, Show, New, Create, Edit - Add any additional needed static files to public folder
- Check for Syntax errors
- setup package.json for deployment
Setup For API with Testing
- Create a directory for the project
- Create a
server.jsfile - Run
npm init -yto initialize a Node project in the directory - Install the necessary packages:
npm install express morgan jest supertest mongodb-memory-server artillery mongoose dotenv - Require Express in
server.js:const express = require('express') - Create an instance of an express app:
const app = express() - Make your app listen on a certain port:
app.listen(3000, () => console.log("Running on port 3000!")) - Require all middleware, including Morgan for logging:
const morgan = require('morgan')and use it:app.use(morgan('dev')) - Set up
.envand.gitignorein your.envadd yourMONGO_URIand in.gitignoreignore your node_modules and .env file - Set up your models and connect your database
- Set up your controllers and route handlers
- Install and configure Jest and Supertest for testing your API routes
- Write tests for your API routes using Jest and Supertest
- Install and configure mongodb-memory-server for running tests using a separate in-memory database
- Write and run tests against the in-memory database
- Install and configure Artillery for load testing your API
- Write and run Artillery tests to ensure your API can handle high loads
- Check for Syntax errors
- Update package.json scripts for running tests:
"test": "jest" - Update package.json scripts for running load tests:
"loadtest": "artillery run ./loadtest.yml" - Setup package.json for deployment
Deployment
- Get a domain and add the nameservers for your cloud provider i.e Digital Ocean
- Create droplet/virtual machine and set up DNS
- SSH into VM and install
nodejs npm ranger neovim nginxthe installnpm i -g n pm2andsnap install certbot --classic - Create an SSH Key for your vm and connect it to github
- Git clone your project to the vm
- install dependencies, set up .env and start project with pm2
- Set up nginx with proxypass to the port running your app
- Set up certbot for https
Functional Testing
| Testing Category | Action Category | Action Description |
|---|---|---|
| Positive Test Category | ||
| Execute Api with valid required parameters | ||
| Validate Status Code | All requests should return 2XX HTTP response depending on spec | |
| Validate Payload | Response should be valid JSON response and the response matches the data model | |
| Validate State of Data/System | GET Requests should not change any data, POST, DELETE, PUT, PATCH should modify system as expected | |
| Validate Headers | Verify that HTTP Headers have valid information, verify nothing is leaked in the headers that doesn't belong | |
| Performance Sanity Check | Verify that data is received in a timely manner | |
| Positive + optional parameters | ||
| Execute API call with valid required parameters AND valid optional parameters | ||
| Validate Status Code | As in group 1 | |
| Validate Payload | As in group 1 | |
| Validate State | As in group 1 | |
| Validate Headers | As in group 1 | |
| Performance Sanity | As in group 1 | |
| Negative Testing - valid input | ||
| Execute API calls with valid input that attempts illegal operations | ||
| Validate Status Code | Verify that an erroneous HTTP status code is sent (NOT 2XX) | |
| Validate payload | Verify that error response is received | |
| Validate Headers | As in group 1 | |
| Performance Sanity | Make sure errors are received in a timely and safe way | |
| Negative testing – invalid input | ||
| Execute API calls with invalid input | ||
| Validate Status Code | As in group 1 | |
| Validate State | As in group 1 | |
| Validate Headers | As in group 1 | |
| Performance Sanity | As in group 1 | |
| Destructive Testing | ||
| Intentionally attempt to fail the API to check its robustness | ||
| Validate Status Code | API should fail gracefully | |
| Validate State | API should fail gracefully | |
| Validate Headers | API should fail gracefully | |
| Performance Sanity | API should fail gracefully |
Remember to review these notes and understand each concept. Happy studying!