@netherium/api-gen
Version:
Generator for Express Rest Api written in Typescript that provides convenient authorization, access control lists and routes following best practices.
404 lines (295 loc) • 13.6 kB
Markdown
<p align="center">
<img src="https://raw.githubusercontent.com/Netherium/api-gen/master/img/repo-logo-760x480.png" alt="Neth-api-gen" width="380">
</p>
<h4 align="center">A powerful RESTful Headless CMS written in Typescript using <a href="https://github.com/expressjs/express" target="_blank">Express</a> and <a href="https://angular.io/" target="_blank">Angular</a></h4>
<h5 align="center">JWT auth, Access-Control Lists (ACL), Uploads, MongoDB, Angular and Angular Material in one :package: </h5>
<p align="center">
<img src="https://img.shields.io/badge/Coverage-99.17%25-brightgreen.svg" alt="Lines Covered">
<img src="https://img.shields.io/badge/Build-Passing-brightgreen.svg" alt="Build Status">
<img src="https://img.shields.io/badge/Node-%3E=12.0.0-grey?logo=node.js&color=339933" alt="Node Version Required">
<img src="https://img.shields.io/badge/Built%20with-Typescript-blue" alt="Built with Typescript">
</p>
<p align="center">
<sub>Made with ❤ by <a href="https://github.com/Netherium">Netherium</a></sub>
</p>
## Table of contents
- [Quick Start](#quick-start)
- [Features](#features)
- [Cli Options](#cli-options)
- [Develop](#develop)
- [Basic API Routes](#basic-api-routes)
- [Resource Permissions](#resource-permissions)
- [Coding Tips](#coding-tips)
- [Structure](#structure)
- [Uploads](#uploads)
- [Under The Hood](#under-the-hood)
- [Tests](#tests)
- [Debug](#debug)
- [Authors](#authors)
- [Copyright and license](#copyright-and-license)
## Quick Start
1. :zap: Npm install <b>globally</b>
```bash
$ npm i -g @netherium/api-gen
```
2. :rocket: Launch
```bash
$ neth-api-gen
```
3. :computer: Fill in choices
<img src="https://raw.githubusercontent.com/Netherium/api-gen/master/img/cli.png">
4. :pray: If you generated project, navigate and install dependencies
Server
```bash
$ cd myproject/server
$ npm install
$ copy `.env.sample` to `.env` and adjust credentials
$ npm run dev
```
Navigate to http://localhost:4000/api/auth/init to initialize app
Client
```bash
$ cd myproject/client
$ npm install
$ npm run start (or ng serve)
```
Navigate to http://localhost:4200 and login with your credentials
<p align="center">
<img src="https://raw.githubusercontent.com/Netherium/api-gen/master/img/admin-panel-login.png" alt="Admin Panel Login">
</p>
All resources are located in the sidenav under `Resources`
<p align="center">
<img src="https://raw.githubusercontent.com/Netherium/api-gen/master/img/admin-panel-sidenav.png" alt="Admin Panel Sidenav">
</p>
## Features
- Typescript Intellisense Awesomeness throughout backend and UI
- Robust routing and middleware based on same principles of Express
- Solid modularized admin panel with [Angular](https://angular.io) and [Angular Material](https://material.angular.io)
- MongoDB integration
- Fuzzy search with 'mongoose-fuzzy-searching'
- Protected routes, ACL based with middleware, using [`jwt-token`](https://jwt.io)
- File Upload routes and thumbnail generator
- Test and Coverage
- REST API Documentation via [swagger-ui-express](https://www.npmjs.com/package/swagger-ui-express)
- Various helper files and tools, i.e. CORS integration, swagger.yaml, .env environment setup
- Several scripts for easy development and testing
## Cli Options
1. :dash: Gimmie my API!!!
- `neth-api-gen`
- Select `app`
- Add entities according to your needs
- Get a production ready(:crossed_fingers:) api + admin panel including [basic routes](#basic-routes) + the entities you've added ([ACL required](#resource-permissions))
- Impress your team!
2. :bulb: I forgot to add...
- `neth-api-gen`
- Select `entities`
- Add more entities to your existing neth-api-gen project, or a solid boilerplate for an ExpressJs/Angular project (modifications may apply)
- Go and play!
3. :joystick: I want more control and faster!!!
- `neth-api-gen -i mysample.json`
- Import all the options from a json file, instead of a UI
- Do it once, do it many!
4. :confused: But where is that JSON???
- `neth-api-gen -s`
- Oh yeah, forgot to mention it
5. :question: Can you help???
- `neth-api-gen -h`
- I can
:warning: When `generateApp: true`, `swaggerDocs` is irrelevant, but you need to provide `swaggerPath: "myproject/swagger.yaml"`
## Develop
1. :pray: If you generated project, navigate and install dependencies
Server
```bash
$ cd myproject/server
$ npm install
```
Client
```bash
$ cd myproject/client
$ npm install
```
2. :evergreen_tree: Setup your environment files:
Server `.env`, `.env.test`, `.env.production`, according to `.env.sample` (under myproject/server)
```bash
ADDRESS=localhost
PORT=4000
MONGODB_URL=mongodb://localhost:27017/YOUDBNAMEHERE
SECRET=YOURSECRETHERE
...
```
Client `environment.ts`, `environment.prod.ts` (under myproject/client/environments)
```bash
apiUrl: 'http://localhost:4000/api', // Endpoint of the server
authorizedRole: ['Admin'] // Roles that have authorized access to admin panel
...
```
3. :dash: Develop
Server
```bash
$ npm run dev
```
Client
```bash
$ npm run start (ng serve)
```
4. :bulb: 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
5. :rocket: Build!
Server
```bash
$ npm run build
```
Client
```bash
$ npm run build
```
6. :fireworks:Your build is ready to deploy !:fireworks:
## Basic Routes
The basic routes provided are listed below.
Each one of them is being reflected by its own `route`, `controller`, `model`
#### Auth
- :unlock: `api/auth/register` [POST]
- :unlock: `api/auth/login` [POST]
- :closed_lock_with_key: `api/auth/profile` [GET, PUT, DELETE]
- :unlock: `api/auth/init` [GET]
#### Roles
- :closed_lock_with_key: `api/roles` [GET, GET `/:id`, POST, PUT `/:id`, DELETE `/:id`]
#### Resource-Permissions
- :closed_lock_with_key: `api/resource-permissions` [GET, GET `/:id`, POST, PUT `/:id`, DELETE `/:id`]
#### Users
- :closed_lock_with_key: `api/users` [GET, GET `/:id`, POST, PUT `/:id`, DELETE `/:id`]
#### Media-Objects
- :closed_lock_with_key: `api/media-objects` [GET, GET `/:id`, POST, PUT `/:id`, DELETE `/:id`]
#### Docs
- :unlock: `api/docs` [GET]
#### Root
- :unlock: `/` [GET]
#### Endpoints
- :closed_lock_with_key: `api/endpoints` [GET]
#### Books (Provided example Resource Route)
- :closed_lock_with_key: `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 `article.route.ts`
```typescript
export class ArticleRoute {
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.
```bash
POST api/resource-permissions
{
resourceName: 'articles',
methods: [
{
name: 'list',
roles: [PublicRoleId]
},
{
name: 'create',
roles: [AdminRoleId, RegisteredUserRoleId]
}
]
}
```
:warning: **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 :blossom:
Server
.
├── dist # Compiled files ready to deploy `npm run build`
├── 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
Client
.
├── dist # Compiled files ready to deploy `npm run build`
│
├── src # Your code goes here
│ ├── app
│ │ ├── components # Shared components throughout the Angular app
│ │ ├── models # Shared models throughout the Angular app
│ │ ├── services # Shared core services throughout the Angular app
│ │ ├── dialogs # Shared dialogs
│ │ ├── modules # Lazy loaded modules, each generated resource corresponds to 1 module
│ │ └── app-routing.module.ts # Routing module that binds all lazy loaded modules, each generated resource has a child under `childrenRoutes`
│ ├── assets # Static resources
│ ├── environments # Angular environment configuration
│ ├── theming # Angular Material Theming Styles
│
... Rest Default Angular Structure
## Uploads
- Uploads can be stored locally or remotely, see `.env`
- To upload a file `POST api/uploads` with `Content-Type: multipart/form-data;` or use [Postman](https://www.postman.com/)
- Field `file` is the file data, `altenativeText`, `caption` are optional strings
- `PUT api/uploads/:id` accepts `Content-Type: application/json;` as only `altenativeText`, `caption` can be modified
- If file of image type, a thumbnail (80x80) will be generated
## Under The Hood
- When you generate an `App`
- an **Express project** based on [Neth-express-api-ts](https://github.com/Netherium/neth-express-api-ts) is created
- an **Angular project** based on [Neth-ng](https://github.com/Netherium/neth-ng) is created
- When you generate an `Entity`, multiple files are generated under `server` and `client` folders
Server
- Controller, Model, Route files are generated under their corresponding folders `./server/src/controllers/entity.controller.ts, ./server/src/models/entity.model.ts, ./server/src/routes/entity.route.ts`
- An entry in `server.ts` is created, under method `routes`
Client
- A module is created under its corresponding folder `./client/src/app/modules/entityfolder/...`
- An entry in `app-routing.module.ts` is created, under variable `childrenRoutes`
## Tests
- Server testing based on [Mocha](https://www.npmjs.com/package/mocha), [chai](https://www.npmjs.com/package/chai) and [chai-http](https://www.npmjs.com/package/chai-http)
- Client testing based on the default Angular test tools [Jasmine](https://angular.io/guide/testing)
<sub>(Tests not provided/generated for Angular, but you can follow standard Angular practices)</sub>
Run tests
Server
```bash
$ cd myproject/server
$ npm test
```
Client
```bash
$ cd myproject/client
$ npm test (or ng test)
```
## Coverage
Server Coverage is based on [nyc](https://www.npmjs.com/package/nyc)
Run coverage (generated under folder `coverage`)
```bash
$ 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`
<img src="https://raw.githubusercontent.com/Netherium/api-gen/master/img/debug_setup.png">
## Authors
**[Netherium](https://github.com/Netherium)**
## Copyright and license
Code released under [the MIT license](https://github.com/Netherium/api-gen/blob/master/LICENSE)