Implementation of friendship graph with degrees of separation
To create the project, follow these steps:
Clone the repo:
git clone https://github.com/cs12b015/friendship-graph.git
cd friendship-graph
Install the dependencies:
yarn install
Set the environment variables:
cp .env.example .env
# open .env and modify the environment variables (if needed)
- Features
- Commands
- Environment Variables
- Project Structure
- API Endpoints
- Error Handling
- Validation
- Logging
- Linting
- SQL database: sqlite3 object data modeling using Sequelize
- Validation: request data validation using Joi
- Logging: using winston and morgan
- Testing: unit and integration tests using Jest
- Error handling: centralized error handling mechanism
- Dependency management: with Yarn
- Environment variables: using dotenv
- Security: set security HTTP headers using helmet
- Santizing: sanitize request data against xss and query injection
- CORS: Cross-Origin Resource-Sharing enabled using cors
- Compression: gzip compression with compression
- Git hooks: with husky and lint-staged
- Linting: with ESLint and Prettier
- Editor config: consistent editor configuration using EditorConfig
Running locally:
yarn dev
Running in production:
yarn start
Testing:
# run all tests
yarn test
# run all tests in watch mode
yarn test:watch
# run test coverage
yarn coverage
Linting:
# run ESLint
yarn lint
# fix ESLint errors
yarn lint:fix
# run prettier
yarn prettier
# fix prettier errors
yarn prettier:fix
The environment variables can be found and modified in the .env
file. They come with these default values:
# Port number
PORT=3000
# Node environment
NODE_ENV=development
src\
|--config\ # Environment variables
|--controllers\ # Route controllers (controller layer)
|--middlewares\ # Custom express middlewares
|--migrations\ # SQL Data migrations to create tables
|--models\ # Sequelize models (data layer)
|--routes\ # Routes
|--seeders\ # SQL Data Seeders
|--services\ # Business logic (service layer)
|--utils\ # Utility classes and functions
|--validations\ # Request data validation schemas
|--app.js # Express app
|--index.js # App entry point
List of available routes:
User routes:
GET /api/search/:userId/:query
- search users
GET /api/friend/:userId/:friendId
- to friend a user
GET /api/unfriend/:userId/:friendId
- to unfriend a user\
The app has a centralized error handling mechanism. Controllers should try to catch the errors and forward them to the error handling middleware (by calling next(error)
).
The error handling middleware sends an error response, which has the following format:
{
"success": false,
"error": "Not found"
}
Request data is validated using Joi. Check the documentation for more details on how to write Joi validation schemas.
The validation schemas are defined in the src/validations
directory and are used in the routes by providing them as parameters to the requestValidator
middleware.
const { Router } = require('express');
const { requestValidator } = require('../middlewares');
const { usersValidation } = require('../validations');
const { usersController } = require('../controllers');
const router = Router();
router.get(
'/search/:userId/:query',
requestValidator(usersValidation.search),
usersController.search
);
Import the logger from src/utils/logger.js
. It is using the Winston logging library.
Logging should be done according to the following severity levels (ascending order from most important to least important):
const logger = require('<path to src>/config/logger');
logger.error('message'); // level 0
logger.warn('message'); // level 1
logger.info('message'); // level 2
logger.http('message'); // level 3
logger.verbose('message'); // level 4
logger.debug('message'); // level 5
In development mode, log messages of all severity levels will be printed to the console.
In production mode, only info
, warn
, and error
logs will be printed to the console.
Note: API request information (request url, response code, timestamp, etc.) are also automatically logged (using morgan).
Linting is done using ESLint and Prettier.
In this app, ESLint is configured to follow the Airbnb JavaScript style guide with some modifications. It also extends eslint-config-prettier to turn off all rules that are unnecessary or might conflict with Prettier.
To modify the ESLint configuration, update the .eslintrc.json
file. To modify the Prettier configuration, update the .prettierrc.json
file.
To prevent a certain file or directory from being linted, add it to .eslintignore
and .prettierignore
.
To maintain a consistent coding style across different IDEs, the project contains .editorconfig