This project has been made for the festival named "Les 24 heures de l'INSA" that takes place in Lyon in France. The festival offers three things : concerts, activities and races. That API will be used by organizers to manage people that want to participate to the races, their registration and so on.
The API project is developped with NodeJS and Express module.
The database used is MySQL with Sequelize module as ORM.
- Configure the file
config/config-database-dev.json
and remove the extension-dev
. Fill the missing fields as user, password of mysql... - Go to config directory
cd ./config
and generate certificate for httpsopenssl req -newkey rsa:2048 -nodes -keyout key.pem -x509 -days 365 -out cert.pem
. - Dowload
docker
anddocker-compose
on your computer - Create the docker network for inter container communication
docker network create courses24maker-network
- Customize the
docker-compose.yml
(not mandatory, only if you want set the ports for example) - In the current folder where is located
docker-compose.yml
launchdocker-compose up
. Two containers are lauched (the database and the api server). Now, the api server is listening on the port 3020 (unless you have changed it in thedocker-compose.yml
file).
- Dowload and open your IDE as IntelliJ or Webstorm (optionally)
- If not yet, dowload NodeJS and npm, then update your PATH variable.
Make sure with the commands :node --version
andnpm --version
- Clone the project on your workspace :
git clone https://gitlab.com/johnratignier/courses24maker-api.git
- As all dependencies and frameworks come from npm packages, you can install all by using the following command :
npm install
- Configure the file
config/config-authentication-dev.json
and remove the extension-dev
. Fill the missing fields as rsa key, admin password and so on... It's mandatory for the authentication process of the application
- Dowload MySQL Server (and optionally MySQL Workbench for the GUI).
- Import the latest database dump (.sql) available in ./db/ directory.
mysql -p -u [user] [database] < ./db/database-script-creation.sql
That will create and provision the database named db_courses24maker_api. - Configure the file
config/config-database-dev.json
and remove the extension-dev
. Fill the missing fields as user, password of mysql... - Start MySQL Server. It will listen on port 3306.
- Lauch the application server with the command :
npm run start_dev
- Open your browser and go at http://localhost:8080/
|-- apidoc //The documentation generated by apidoc module
|
|-- bin //Start file
| |-- www.js
|
|-- config //All configuration files
| |-- config-authentication.json (not commited)
| |-- config-authentication.js
| |-- config-database.json (not commited)
| |-- config-database.js
|
|-- db //To store dump adn script of the db
| |-- database-script-creation.sql
|
|-- documents (not commited) //To store documents of the api
| |-- database-script-creation.sql
|
|-- models //All models configuration to link database and code (Sequelize ORM code)
| |-- category.js
| |-- participant.js
| |-- team.js
|
|-- node_modules (not commited) //The default package that store all node modules
| |-- ...
|
|-- routes //All routes defined to respond to incoming API requests
| |-- authentication.js
| |-- category.js
| |-- participant.js
| |-- team.js
|
|-- services //All services and necessary business code used by routes
| |-- service-authentication.js
| |-- service-category.js
| |-- ...
|
|
|-- package-lock.json
|-- package.json
|-- docker-compose.yml //The script to lauch all services of the api
|-- Dockerfile-application //The dockerfile to build the node-service in a docker container
|-- Dockerfile-database //The dockerfile to build the mysql-service in a docker container
|-- app.js //The first entrypoint when the application server in lauched (after bin/www)
|-- README.md
Thanks to Express, we can create and launch a webserver. This one will respond to external requests as a classical webserver.
We will defined all the routes with an organized "path architecture" to respond to each request. According to the request path, the request method and the request parameters passed,
that server will respond to the client (who has sent the request) with object or informations.
Before starting it's important to understand what Middleware are.
First, we can say that the express application (the API) is represented by app
variable.
Middleware are functions that will be in the middle between the application and incoming requests.
For example, there are middlewares to parse the incoming request body, to encode URL, to store session,... It exists so many middleware (modules)
to simplify our work and make some ingrateful tasks.
To use a middleware you have to import it and to add it to the application with the command app.use()
.
The middlewares are executed one after the other, so take care to the order.
Before starting it's also important to understand what Promises are. To sum up, promises are value that will be available in the future. A promise can be resolved or rejected. If it's resolved, the value become available and can be treated in then() clause, otherwise an error or other object are sent to catch().
In app.js
, first, you must declare all main routes that will be implemented in /routes/
:
var fileRouteRouter = require('./routes/fileRoute');
app.use("/pathToRoute", fileRouteRouter);
Thus, all request whose the path start with /pathToRoute
will be forwarded and handled by fileRoute
.
The requests must be handled in /routes/
directory in a particular file.
Each request will be catch by the appropriate function according to its path and method.
var router = express.Router();
router.get('/mail/:id', function(req, res, next) {
//Here the instruction to do when client make GET request to /pathToRoute/mail/id where id is the parameter
//After that a response must be sent to the client
});
router.post('/mail/', function(req, res, next) {
//Here the instructions to do (insert new user in db).
//After that a response must be sent to the client.
});
module.exports = router;
Consult the official documentation that's very useful: http://docs.sequelizejs.com.
Sequelize enable Database mapping. That's to say all table are mapped on the Node code thank's to object instantiate by Sequelize.
All accesses to the database will be performed with Sequelize.
The configuration link is very simple and set with database configuration in /config/config_database
.
Each table of the database is defined as a model in /models/[table_name].js
.
When you add a new table or a new field of an existing table of the database, you have to alter the corresponding models. Refer to an existing one to create a new model or a new field. Take care to have a good mapping between the model and the table, otherwise errors will occur.
You can generate theses models by using sequelize-auto
module with the command:
node ./node_modules/sequelize-auto/bin/sequelize-auto -h localhost -d db_courses24maker_api -u [user] -x [password]
Refer to documentation: http://docs.sequelizejs.com/manual/tutorial/models-usage.html and http://docs.sequelizejs.com/manual/tutorial/querying.html.
Note that Sequelize uses promises that return an instance of an object defined by the appropriate model (if no error). For example :
//Import UserModel, sequelize and all necessary modules
UserModel.findAll({where: {id: userId}}) //You can make some types of query (findAll, findOne, findAndCount, ... with some clauses)
.then(userResult => { //userResult is an instance of the object defined in /models/UserModel.js
console.log('user found : '+ userResult.name);
})
.catch(err =>{
console.log('error : '+err);
});
You can create an object instance defined in /models/ to prepare an entry that could be insert in the database.
const userInstance = UserModel.build({
id: userId
name: userName,
surname: userSurname
});
console.log(userInstance.surname);
userInstance.save() //To insert in database
.then( ()=>{} )
.catch( err=>{} );
All documentation is generated by apidoc module. To write the documentation, you have to make some annotations above each router method. For example :
/**
* @apiGroup CATEGORY
* @api {GET} /categories/:id Delete a category
* @apiDescription Delete a category
* @apiPermission admin
* @apiUse Header
* @apiParam (Path) {String} id ``Mandatory`` The uuid of the category to delete
* @apiSuccess (Sucess 204) - No Content
* @apiUse GenericAuthenticationError
* @apiError (Error 4xx) {404} CATEGORY_NOT_FOUND The category has not been found
* @apiError (Error 5xx) {500} CATEGORY_ERROR_INTERNAL_DELETE_CATEGORY An internal error occurs
*/
More information on the official documentation website : http://apidocjs.com/.
To generate the api documentation lauch the command : apidoc -i routes/ -o apidoc/
The generated documentation is available at /apidoc/index.html
. All depedencies are in the same folder apidoc/
.