An open API service indexing awesome lists of open source software.

https://github.com/jimlynchcodes/crud-lambda-typescript-mongo

A little serverless lambda providing CRUD functionality for a MongoDB collection! 🎉
https://github.com/jimlynchcodes/crud-lambda-typescript-mongo

Last synced: 4 months ago
JSON representation

A little serverless lambda providing CRUD functionality for a MongoDB collection! 🎉

Awesome Lists containing this project

README

          

# CRUD-Lambda-TypeScript-Mongo

A little serverless lambda providing CRUD functionality for a MongoDB collection! 🎉

## Tldr;

Run it with this command:
```
sls offline --skipCacheInvalidation --useSeparateProcesses start
```

This is also aliased as the start command:
```
npm start
```

## End-To-End Tests
The end-to-end tests have been automated with Postman!

To test manually -> Import the `CRUD-Lambdas-TypeScript.postman_collection.json` into Postman!

To test from command line:
```
npx newman run CRUD-Lambdas-TypeScript.postman_collection.json
```
or the npm command:
```
npm run e2e
```

_Note: make sure your local mongoDb when running run End-to-end tests!_

## Unit Tests

Using Mocha configured for typescript as the unit testing framework.

To run unit tests:
```
npm test
```

_Note: you may need to run this command:_
```
npm install -g ts-node
```

# Motivation
As a software engineer, I often find myself recreating a simple backend server that exposes CRUD (create, read, update, and delete) operations. In order to make my future developments faster I have created this project as somewhat of a reference guide.

# Mongo & TypeScript
This "CRUD Lambda" project is written in _TypeScript_ and exposes CRUD operations for the _MongoDB_ database.

TypeScript is an excellent superset of JavaScript that allows the written code to be explicitly about the types of objects and contains an experimental meant to make development more pleasant.

MongoDB is a NoSql database that provides excellent querying & aggregation apis and fantastically balances speed and scalability.

# What It Is

The goal of this project is to have a lambda function that exposes 5 endpoints relating to CRUD operations:

- GET - /books # returns all books
- GET - /books/:id # returns a book with id 1
- POST - /books # inserts a new book into the table
- DELETE - /books/:id # deletes a book with id of 1
- PUT - /books/:id # updates a book with id of 1

Notice that the endpoints in every case are consistent and plural (ie. books with an s). Following this practice is very common and highly recommended.

Our Mongo Database will contain a collection of Books where each books has the same shape as this object:
```
{
"title": "Clojure for the Brave and True",
"author": "Daniel Higginbotham",
"datePublished": "10/15/2015",
"pages": 328
}
```

# Pagination
In addition to the routes listed above, this project exposes an adiitional GET route with pagination. Though this will usually be the default behavior of the base slash route (`/books` in this case), I chose to make it a separate route in this case to illustrate how the implementation of the various routes differ.

The pagination route can be called like so:
```
http://localhost:3000/paginated-books/size=20&after=someBookId
```

This pagination implementation is "cursor pagination" whichi is slightly superior to "offset-limit" pagination because with cursor pagination the results are more what a user would when changing pages after inserting or deleting records from the collection.

### A Nice Explanation of Cursor Pagination
- https://jsonapi.org/profiles/ethanresnick/cursor-pagination/

### Example Implementations of "Cursor Pagination" With The MongoDb Mongoose Library
- https://stackoverflow.com/a/21040304/1910355
- https://stackoverflow.com/a/23640287/1910355

# Usage

## 0. Install Mongo Locally
Following the guide [here](https://github.com/mongodb/homebrew-brew), I used brew:
```
brew tap mongodb/brew
brew install mongodb-community@4.2
```

Then to use this as your default `mongodb-community` run this command:
```
brew link mongodb-community
```

If your mongo is out of control, you can track it down with this:
```
sudo lsof -iTCP -sTCP:LISTEN -n -P
```

and if you need to:
```
kill
```

### 1. Create the .env File

First, copy the `.env_SAMPLE` file and rename it to `.env`:
```
mv .env_SAMPLE .env
```

Enter your mongo credentials in the .env file.

### 2. Use Node v12

If you have nvm this command will use .nvmrc to switch to the correct node version:
```
nvm use
```

### 3. Install Dependencies
```
npm i
```

### 4. Run Local Mongo
```
brew start services mongo
```

FYI - to check if mongo is running:
```

```

Use seed script to enter a few sample books into the collection.
```
./seed-db.sh
```

### 5. Execute Endpoints Locally

#### Option B) With "Serverless Invoke"

#### Option A) With "Serverless Offline"
```
sls offline start
```

#### Calling Endpoints From Postman (Manually)

### 6. Run Unit Tests (Mocha)

### 7. Run End-To-End Tests (Postman From Command Line)

# Mongoose
This repo uses the mongoose library. Mongoose provides an "ORM" whereby you define models and use methods on them to interact with the database. This is nice because it makes it slightly hard to do the wrong thing. 😉

# Shoutouts

This project was proudly scaffolded with the serverless cli:
```
sls create --template aws-nodejs-typescript
```

Shoutout to [this excellent article](https://tutorialedge.net/typescript/typescript-mongodb-beginners-tutorial/) by [Elliot Forbes](https://twitter.com/elliot_f) which served as a great guide for me to follow and use for inspiration!

Shoutout to everyone I've ever worked with for shaping me to be the person I am today. 🙏

# Contributing
Feel free to open Issues or PR's if you have any comments or suggestions. ❤️

Also, feel free to tweet at me here: https://twitter.com/JimLynchCodes