Skip to content

Netherium/neth-express-api-ts

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

59 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Neth-express-api-ts

A RESTful API written in Typescript using Express

JWT auth, Access-Control Lists (ACL), Uploads, MongoDB in one πŸ“¦
Lines Covered Build Status Node Version Required Built with Typescript
Made with ❀ by Netherium

Table of contents

Quick Start

  1. ⚑ Clone this repo

    $ git clone https://github.com/Netherium/neth-express-api-ts
  2. πŸ™ Install dependencies

    $ npm install
  3. 🌲 Setup your environment files: .env, .env.test, .env.production, according to .env.sample

    ADDRESS=localhost
    PORT=4000
    MONGODB_URL=mongodb://localhost:27017/YOUDBNAMEHERE
    SECRET=YOURSECRETHERE
    ....
  4. πŸ’¨ Develop

    $ npm run dev
  5. πŸ’‘ Initialize: Navigate to http://localhost:4000/api/auth/init

    • 2 Roles will be created, 1 Admin, 1 Public
    • 1 User will be created, based on your .env credentials
    • Resource permissions will be created for basic routes, with default access to admin Role
  6. πŸš€ Build!

    $ npm run build

Features

  • Typescript Intellisense Awesomeness
  • Robust routing and middleware based on same principles of Express
  • MongoDB integration
  • Fuzzy search with 'mongoose-fuzzy-searching'
  • Protected routes, ACL based with middleware, using jwt-token
  • File Upload routes and thumbnail generator
  • Test and Coverage
  • REST API Documentation via swagger-ui-express
  • Various helper files and tools, i.e. CORS integration, swagger.yaml, .env environment setup
  • Several scripts for easy development and testing

Basic Routes

The basic routes provided are listed below. Each one of them is being reflected by its own route, controller, model

Auth

  • πŸ”“ api/auth/register [POST]
  • πŸ”“ api/auth/login [POST]
  • πŸ” api/auth/profile [GET, PUT, DELETE]
  • πŸ”“ api/auth/init [GET]

Roles

  • πŸ” api/roles [GET, GET /:id, POST, PUT /:id, DELETE /:id]

Resource-Permissions

  • πŸ” api/resource-permissions [GET, GET /:id, POST, PUT /:id, DELETE /:id]

Users

  • πŸ” api/users [GET, GET /:id, POST, PUT /:id, DELETE /:id]

Media-Objects

  • πŸ” api/media-objects [GET, GET /:id, POST, PUT /:id, DELETE /:id]

Docs

  • πŸ”“ api/docs [GET]

Root

  • πŸ”“ / [GET]

Endpoints

  • πŸ” api/endpoints [GET]

Books (Provided example Resource Route)

  • πŸ” api/books [GET, GET /:id, POST, PUT /:id, DELETE /:id]

Resource Permissions

  • Add a new route with Access-Control List (ACL) by invoking middleware function Auth.getACL() I.e. file book.route.ts
    export class BookRoute {
      constructor() {
        this.router.get('/', Auth.getAcl(), controller.list);
        ...
        this.router.post('/', Auth.getAcl(), controller.create);
      }
    }
  • Add the appropriate resource-permission for this resource for each method (list, create, in this case) and for each method the roles that will have access to.
POST api/resource-permissions
{
    resourceName: 'books',
    methods: [
        {
            name: 'list',
            roles: [PublicRoleId]
        },
        {
            name: 'create',
            roles: [AdminRoleId, RegisteredUserRoleId]
        }
    ]
}

⚠️ If you add at least 1 unauthenticated role then this resource route will be open

Coding Tips

Get Service

  • Register any service in server.ts, under registerServices function
  • Access it anywhere by destructuring it const {uploadService} = req.app.get('services');

Get Authenticated User

  • When a route is authenticated, you can access the authenticated user by res.locals.authUser

Get Resource Permissions

  • For optimization, resource-permissions are stored in app.locals.resourcePermissions. If you update manually a resource (i.e. not via api call, but database manipulation), restart server or call Auth.updateAppPermissions()

Structure

Follow the structure below. It will keep things and your mind tidy 🌼

.
β”œβ”€β”€ dist                # Compiled files ready to deploy `npm run test`
β”œβ”€β”€ uploads             # When using local provider this is where uploads go
β”‚
β”œβ”€β”€ src                 # Your code goes here
β”‚   β”œβ”€β”€ routes          # Routes that define endpoints, methods, handlers and middleware
β”‚   β”œβ”€β”€ controllers     # Controllers that handle functionality from routes
β”‚   β”œβ”€β”€ models          # Mongoose models and typescript interfaces
β”‚   β”œβ”€β”€ middleware      # Middleware functions
β”‚   β”œβ”€β”€ services        # Services in OOP style that can be called in controllers
β”‚   β”œβ”€β”€ helpers         # Exported functions that need no instantiation
β”‚   └── server.ts       # Server entrypoint file
β”‚
β”œβ”€β”€ test                # Automated tests `npm run test`
β”‚
β”œβ”€β”€ swagger.yaml        # Swagger documentation (`api/docs`) defined in yaml format
β”œβ”€β”€ LICENSE             # License file
└── README.md           # This File

Media Objects

  • MediaObjects can be stored locally or remotely, see .env
  • To upload a file POST api/media-objects with Content-Type: multipart/form-data; or use Postman
  • Field file is the file data, altenativeText, caption are optional strings
  • PUT api/media-objects/:id accepts Content-Type: application/json; as only altenativeText, caption can be modified
  • If file is of image type, a thumbnail (80x80) will be generated

Query Parameters

The following query parameters are available for all routes

Key Type Description Example Notes
q Parameter search like api/books?q=rings searches all fields that have fuzzy search enabled
_eq Suffix property equal to api/books?title_eq=Lord of the rings -
_ne Suffix property not equal to api/books?title_ne=Lord of the rings -
_lt Suffix property less than api/books?isbn_lt=1235466 -
_lte Suffix property less or equal api/books?isbn_lte=1235466 -
_gt Suffix property greater than api/books?isbn_gt=1235466 -
_gte Suffix property greater or equal api/books?isbn_gte=1235466 -
_sort Parameter sort by property api/books?_sort=-isbn use - for desc
_limit Parameter limit by a number api/books?_limit=-1 use -1 for unlimited
Default: All list routes have limit=10
_page Parameter get paginated results api/books?_limit=-1 use with _limit

Tests

Testing is based on Mocha, chai and chai-http

Run tests, based on .env.test

$ npm test

Coverage

Coverage is based on nyc

Run coverage (generated under folder coverage)

$ npm run test:coverage

Debug

To debug TS without compiling it, you can setup your IDE of choice as in the example below Note: Running older versions of node may require attaching --inspect before --require

Authors

Netherium

Copyright and license

Code released under the MIT license

Packages

No packages published