A RESTful API written in Typescript using Express
- Quick Start
- Features
- Basic Routes
- Resource Permissions
- Coding Tips
- Structure
- Media Objects
- Query Parameters
- Tests
- Debug
- Authors
- Copyright and license
-
β‘ Clone this repo
$ git clone https://github.com/Netherium/neth-express-api-ts
-
π Install dependencies
$ npm install
-
π² 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 ....
-
π¨ Develop
$ npm run dev
-
π‘ 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
-
π Build!
$ npm run build
- 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
The basic routes provided are listed below.
Each one of them is being reflected by its own route
, controller
, model
- π
api/auth/register
[POST] - π
api/auth/login
[POST] - π
api/auth/profile
[GET, PUT, DELETE] - π
api/auth/init
[GET]
- π
api/roles
[GET, GET/:id
, POST, PUT/:id
, DELETE/:id
]
- π
api/resource-permissions
[GET, GET/:id
, POST, PUT/:id
, DELETE/:id
]
- π
api/users
[GET, GET/:id
, POST, PUT/:id
, DELETE/:id
]
- π
api/media-objects
[GET, GET/:id
, POST, PUT/:id
, DELETE/:id
]
- π
api/docs
[GET]
- π
/
[GET]
- π
api/endpoints
[GET]
- π
api/books
[GET, GET/:id
, POST, PUT/:id
, DELETE/:id
]
- Add a new route with Access-Control List (ACL) by invoking middleware function
Auth.getACL()
I.e. filebook.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]
}
]
}
Get Service
- Register any service in
server.ts
, underregisterServices
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 callAuth.updateAppPermissions()
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
- MediaObjects can be stored locally or remotely, see
.env
- To upload a file
POST api/media-objects
withContent-Type: multipart/form-data;
or use Postman - Field
file
is the file data,altenativeText
,caption
are optional strings PUT api/media-objects/:id
acceptsContent-Type: application/json;
as onlyaltenativeText
,caption
can be modified- If file is of image type, a thumbnail (80x80) will be generated
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=123546 6 |
- |
_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 |
Testing is based on Mocha, chai and chai-http
Run tests, based on .env.test
$ npm test
Coverage is based on nyc
Run coverage (generated under folder coverage
)
$ npm run test:coverage
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
Code released under the MIT license