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 -y
to 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
.env
and.gitignore
in your.env
add yourMONGO_URI
and in.gitignore
ignore 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.css
file within/public/css
and add your styling - Host your
public/
folder:app.use('/assets', express.static('public'))
- Include your CSS in the head of your
views/layout.hbs
file:<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.js
file - Run
npm init -y
to 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
.env
and.gitignore
in your.env
add yourMONGO_URI
and in.gitignore
ignore 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 nginx
the installnpm i -g n pm2
andsnap 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!