MOST Data ORM Extension for ExpressJS
npm i @themost/express
Install @themost/cli globally
npm i @themost/cli -g
Generate a new project by executing the following command:
themost new project my-app --template express
Go to project's directory:
cd my-app
Install dependencies:
npm i
and serve the new application by executing:
npm run serve
Open your browser and navigate to http://127.0.0.1:3000
Use @themost/data application as an express middleware:
import express from 'express';
import path from 'path';
import {ExpressDataApplication, serviceRouter, dateReviver} from '@themost/express';
let app = express();
// data application setup
let dataApplication = new ExpressDataApplication(path.resolve(__dirname, 'config'));
// use @themost/express dateReviver helper function for parsing dates
app.use(express.json({
reviver: dateReviver
}));
// use data application middleware
app.use(dataApplication.middleware(app));
Use the service router for serving all the available data models:
var serviceRouter = require('@themost/express').serviceRouter;
app.use('/api', passport.authenticate('bearer', { session: false }), serviceRouter);
or use the traditional way of serving data:
var peopleRouter = require('./routes/people');
app.use('/people', peopleRouter);
// # people.js
var express = require('express');
var router = express.Router();
/* GET /people get persons listing. */
router.get('/', function(req, res, next) {
req.context.model('Person').filter(req.query).then(function(q) {
return q.getList().then(function(result) {
return res.json(result);
});
}).catch(function(err) {
return next(err);
});
});
/* POST /people insert or update a person or an array of persons. */
router.post('/', function(req, res, next) {
if (typeof req.body === 'undefined') {
return res.status(400).send();
}
req.context.model('Person').save(req.body).then(function() {
return res.json(req.body);
}).catch(function(err) {
return next(err);
});
});
/* GET /person/:id get a person by id. */
router.get('/:id', function(req, res, next) {
req.context.model('Person').where('id').equal(req.params.id).getItem().then(function(value) {
if (typeof value === 'undefined') {
return res.status(204).send();
}
return res.json(value);
}).catch(function(err) {
return next(err);
});
});
/* DELETE /person/:id delete a person by id. */
router.delete('/:id', function(req, res, next) {
req.context.model('Person').where('id').equal(req.params.id).count().then(function(value) {
if (value === 0) {
return res.status(404).send();
}
// construct a native object
var obj = {
"id": req.params.id
};
//try to delete
return req.context.model('Person').remove(obj).then(function() {
return res.json(obj);
});
}).catch(function(err) {
return next(err);
});
});
Use ExpressDataApplication#container to access and extend parent application. The following example represents an application service which extends container application router
# MyApplicationService.js
export class MyApplicationService extends ApplicationService {
constructor(app) {
super(app);
// subscribe for container
app.container.subscribe( container => {
if (container) {
// create a router
const newRouter = express.Router();
newRouter.get('/message', (req, res) => {
return res.json({
message: 'Hello World'
});
});
newRouter.get('/status', (req, res) => {
return res.json({
status: 'ok'
});
});
// use router
container.use('/a', newRouter);
}
});
}
}
# app.js
import {MyApplicationService} from './MyApplicationService';
...
// use data application middleware
app.use(dataApplication.middleware(app));
// add application service
dataApplication.useService(MyApplicationService);
@themost/express#serviceRouter
router may be extended to include extra service endpoints:
# ServiceRouterExtension.js
class ServiceRouterExtension extends ApplicationService {
constructor(app) {
super(app);
app.serviceRouter.subscribe( serviceRouter => {
// create new router
const addRouter = express.Router();
addRouter.get('/users/me/status', (req, res) => {
return res.json({
status: 'ok'
});
});
// insert router at the beginning of serviceRouter.stack
serviceRouter.stack.unshift.apply(serviceRouter.stack, addRouter.stack);
});
}
}
# app.js
const app = express();
// create a new instance of data application
const application = new ExpressDataApplication(path.resolve(__dirname, 'test/config'));
// use extension
application.useService(ServiceRouterExtension);
app.use(express.json({
reviver: dateReviver
}));
// hold data application
app.set('ExpressDataApplication', application);
// use data middleware (register req.context)
app.use(application.middleware(app));
...
// user service router
app.use('/api/', passport.authenticate('bearer', { session: false }), serviceRouter);
ResponseFormatter service formats responses based on Accept
request header.
The available response formatters are:
- JsonResponseFormatter which is the default response formatter and returns JSON response.
- XmlResponseFormatter which returns XML response.
A response formatter may be added in ResponseFormatter#formatters collection:
// add application/json formatter
this.formatters.set('application/json', JsonResponseFormatter);
// add application/xml formatter
this.formatters.set('application/xml', JsonResponseFormatter);
An example of custom formatter:
class MyJsonFormatter extends HttpResponseFormatter {
execute(req, res) {
return res.json(data);
}
}
Note: ResponseFormatter is not enabled by default and it should be registered after application initialization.
import express from 'express';
import path from 'path';
import {ExpressDataApplication, serviceRouter, dateReviver, ResponseFormatter} from '@themost/express';
let app = express();
// data application setup
let dataApplication = new ExpressDataApplication(path.resolve(__dirname, 'config'));
// initialize response formatter
dataApplication.useService(ResponseFormatter);