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

https://github.com/danpoynor/school-admin-sql-rest-api

Demo REST API developed using Node.js, Express, and Sequelize provides a way to administer a school database containing information about users and courses.
https://github.com/danpoynor/school-admin-sql-rest-api

api-server api-testing authentication bcryptjs demo-app expressjs middleware nodejs postman postman-collection postman-test rest-api sequelize validations

Last synced: 7 months ago
JSON representation

Demo REST API developed using Node.js, Express, and Sequelize provides a way to administer a school database containing information about users and courses.

Awesome Lists containing this project

README

          

# School Admin SQL REST API

Demo REST API developed using Node.js, Express, and Sequelize provides a way to administer a school database containing information about users and courses.

---

## Running the App

Assuming you have `node` and `npm` already installed globally on your system - clone this repo, `cd` into the app folder, then install dependencies:

```bash
git clone https://github.com/danpoynor/school-admin-sql-rest-api.git
cd school-admin-sql-rest-api/
npm install
```

In the terminal run the `npm run seed` command. This will create the `fsjstd-restapi.db` database and seed it with initial data. Then start the app with `npm start`

```bash
npm run seed && npm start
```

In your terminal output, you should see something similar to the following:

```bash
✅ 8 Routes found: [
{ path: '/', method: 'GET' },
{ path: '/api/courses/', method: 'GET' },
{ path: '/api/courses/', method: 'POST' },
{ path: '/api/courses/:id', method: 'GET' },
{ path: '/api/courses/:id', method: 'PUT' },
{ path: '/api/courses/:id', method: 'DELETE' },
{ path: '/api/users/', method: 'GET' },
{ path: '/api/users/', method: 'POST' }
]
✅ Express server is listening on port 5000
✅ Connection to 'sqlite' database 'fsjstd-restapi.db' established.
✅ Model 'Course' is defined. Table name is 'Courses'.
✅ Model 'User' is defined. Table name is 'Users'.
✅ 2 Tables found: [ 'Users', 'Courses' ] (Uncomment lines below to copy model starters)
```

Visiting in a web browser you should see a "Welcome to the REST API project!" message.

The `RESTAPI.postman_collection.json` file can be imported into [Postman](https://www.postman.com) to manually test the application. Or import `RESTAPI.postman_collection--with-tests.json` to run 63 automated test assertions (see [note below](#postman-test-collection)).

Or, use the `tests.http` file as an alternative method for testing the application. You'll need to install the [REST Client](https://marketplace.visualstudio.com/items?itemName=humao.rest-client) package as a dependency in order to run the tests in this file.

---

## Project Features

- REST API Validation
- User Authentication Middleware using [bcryptjs](https://www.npmjs.com/package/bcryptjs).
- `isEmail` validation of the emailAddress attribute in the User model to ensure that the provided email address is properly formatted.
- `unique` constraint to the User model to ensure that the provided email address isn't already associated with an existing user.
- `len` validation to the User model to ensure that the provided password is between 7 and 50 characters long.

- [Express Hook](https://sequelize.org/docs/v6/other-topics/hooks/) `afterValidate` used to encrypt the User password with [bcryptjs](https://www.npmjs.com/package/bcryptjs)
after it's validated and before it's saved to the database.

---

## API Endpoints

GET / Returns the message "Welcome to the REST API project!"

GET /api/users Returns all properties and values for the currently authenticated User including Courses they own



HTTP Status
Message
Notes




200 OK


User authenticated.
Returns all user properties and values.


  • User authenticated.

  • Returns all user properties and values including `Courses` the user owns.

  • Filters out `password`, `createdAt`, and `updatedAt` values.





401 UnauthorizedAccess DeniedUser is not authenticated.


404 Not Found
User not found
An authenticated user should always be able to find their own user record, so this might never be seen.

POST /api/users Creates a new user



HTTP Status
Message
Notes




201 Created



  • Current user is not authenticate before creating a new user.

  • Returns no content.

  • Set the Location header to /.





400 Bad Request


  • First Name value is required

  • Last Name value is required

  • Password value is required

  • Password must 7 - 50 characters long


  • Email Address value is required

  • Email Address format is invalid

  • Email Address must be unique

  • User already exists





GET /api/courses Returns all courses including the User associated with each course



HTTP Status
Message
Notes




200 OK



  • Returns all courses including the User associated with each course.

  • Filters out `createdAt`, and `updatedAt` values.




GET /api/courses/:id Returns the corresponding course including the User associated with that course



HTTP Status
Message
Notes




200 OK



  • Returns the corresponding course including the User associated with that course.

  • Filters out `createdAt`, and `updatedAt` values.





404 Not Found
Course not found


POST /api/courses Create a new course, set the Location header to the URI for the newly created course



HTTP Status
Message
Notes




201 Created



  • User authenticated.

  • Returns no content

  • Set the Location header to the URI for the newly created course





400 Bad Request


  • Title is required

  • Description is required

  • User Id is required.






401 Unauthorized
Access Denied
User is not authenticated.

PUT /api/courses/:id Update the corresponding course



HTTP Status
Message
Notes




204 No Content



  • User authenticated.

  • Returns no content.

  • Course successfully updated.





400 Bad Request


  • Title is required

  • Description is required






401 Unauthorized
Access Denied
User is not authenticated.


403 Forbidden
Access Denied. You are not the owner of this course.
Current user is not the course owner.

DELETE /api/courses/:id Delete the corresponding course



HTTP Status
Message
Notes




204 No Content



  • User authenticated.

  • User is course owner.

  • Returns no content.

  • Course successfully deleted.





401 Unauthorized
Access Denied
User is not authenticated.


403 Forbidden
Access Denied. You are not the owner of this course.
Current user is not the course owner.


404 Not Found
Course not found.
Tries to find the course before authenticating the owner.

---

## Postman Test Collection

The file `RESTAPI.postman_collection--with-tests.json` includes 63 API endpoint tests ([view Postman Test docs](https://learning.postman.com/docs/writing-scripts/script-references/test-examples/)). To run the collection of tests in [Postman](https://www.postman.com), click the three dots to the right of the name and select `Run Collection` in the dropdown menu ([more info](https://learning.postman.com/docs/running-collections/intro-to-collection-runs/#running-your-collections)).

Note: You'll need to run `npm run seed` before running the tests each time since some endpoints manipulate the database.

View sample list of included tests

Get Users (With Auth)

- "Status code is `200 OK`"
- "Response has a JSON body"
- "Response type should be a JSON object"
- "User `id`, `firstName`, `lastName`, `email` is returned"
- "User owned `courses` array is returned"
- "Courses length is 2"
- "Response should not include `password`, `createdAt`, `updatedAt`"

Create User (with dynamic values)

- "Status code is `201 Created`"
- "Response should contain no content"
- "`Location` header is `/`"

Create User (Existing Email Address) - EXCEEDS

- "Status code is 400 Bad Request"
- "Response has a JSON body"
- "'Email Address must be unique' error message should be returned"

Get Courses

- "Status code is `200 OK`"
- "Response has a JSON body"
- "Response type should be a JSON array"
- "Should return more than 1 courses"
- "Should contain some correct titles"
- "Course owners `firstName` and `lastName` should be included with each course"
- "Response should not include `createdAt`, `updatedAt`"

etc...

---

## Other Notes

- `sequelize.getDatabaseName()` returns `undefined` even though `.authenticate()` will return successful when `dialect` is set to `sqlite`. The function does not read the `config.json` `storage` value, so I kept the `database` value in `config.json`, even though I don't think it should be needed. Potential Sequelize issue or feature request needed to fix this, perhaps.
- When the app first starts, the fancy logging messages in the terminal (with ✅ and ❌ icons) are my development sanity checks indicating the app is correctly configured initially and I haven't broken anything. If this code ever sees a production environment, I would remove the messages or use [`debug`](https://www.npmjs.com/package/debug) for logging.