-
Notifications
You must be signed in to change notification settings - Fork 0
3.1 MOD.001 : REST API (Backend)
- Changelog
- 1. Scope
- 2. Definitions
- 3. Module Requirements
- 4. Analysis
- 5. Design
- 6. Implementation
- 7. Module Test
- 8. Summary
- 9. Appendix
Version | Date | Author | Comment |
---|---|---|---|
0.1 | 16.01.2021 | Namid Marxen und Nils-Christopher Wiesenauer | created |
1.0 | 14.05.2021 | Namid Marxen und Nils-Christopher Wiesenauer | finished |
The Module Documentations (MODs) describes the architecture, the interfaces and the main features of the module. It also describes the module/component test including the results. It can also serve as a programming or integration manual for the module. If there are some risks related to the module itself, they shall be noted and commented within this document.
AML: Automation Markup Language
CRUD: Create Read Update Delete
GUI: Graphical User Interface
JSend: A specification that lays down some rules for how JSON responses from web servers should be formatted
SAS: System Architecture Specification
SRS: System Requirements Specification
This REST API is the most important module because it contains the logic for converting the AML file to JSON. It also includes the authorization to the database. When a file is uploaded to the server it is converted from an AML format to a JSON format so that it can be saved in the MongoDB database. The content of the files are saved as a string and then converted into one JSON object, so that each file has their own database entry, with the JSON object as the content.
When the file upload was successful and is now temporarily saved on the server, the system should convert the file to a JSON format, so it can be saved in a MongoDB database. The file should be converted by writing one JSON object with the file content as a string. If this was successful the user sees a success message that the file was saved. When an error occurs during the conversion process, the user is shown an error.
The REST API is the core of the project. It communicates with the GUI and Database.
The GUI communicates with the REST API via GET/POST/PUT/DELETE request and gets responses via JSend from the REST API.
To provide the neccessary functionalities, the module has 5 submodules for different database operations. The database operations require a connection to the database.
The REST API module needs to convert an uploaded AML file to JSON and then upload it to the database. These files also need to be accessed by the GUI afterwards. You also have to be able to edit and delete these files.
Therefore the module contains the 5 submodules, "Get AML Files", "Upload AML File", "Get AML File by id", "Edit AML File" and "Delete AML File" to provide these functionalities.
When an error occurs, the user need to be informed about the error, for example if he tried to upload an invalid AML file.
The backend contains different files and program code. It is important to understand the file structure and architecture of the aml-database-management-api.
Architecture
All important files and folders are listed below:
-
/models
: This folder contains all mongoose models. Such as file.js -
.env
: This is the environment file of our project, based on the npm package dotenv. Important values like DB_PORT, DB_Domain, DB_TABLE, DB_USER and DB_PASSWORD are included here. -
.gitignore
: This file is a text file that tells Git which files or folders to ignore in a project. In our case, we igored "/node_modules". -
.prettierrc.json
: This file defines how the code should be formatted with Prettier, a Opinionated Code Formatter. Our code will be formatted by running "npm run format". -
README.md
: This file contains information about other files in a directory or archive of computer software. -
package-lock.json
: This file is automatically generated for any operations where npm modifies either the node_modules tree, or package.json. It describes the exact tree that was generated, such that subsequent installs are able to generate identical trees, regardless of intermediate dependency updates. -
package.json
: This file contains all npm packages and holds various metadata relevant to the project. This file is used to give information to npm that allows it to identify the project as well as handle the project's dependencies. -
server.js
: This file is the main part of our REST API. It contains all endpoints, the database connection and the conversion from a .aml file to .json. -
aml-api-documentation.json
/aml-api-documentation.yaml
: This file describes the structure of our API. They are created with Swagger
This module is the main part for the communication with the frontend. It contains every endpoint for upload, edit, download and delete. It includes the database connection to MongoDB and the initial setup for the backend server too. These modules are described seperately in sub modules. The risks and how to handle them, are documented in the mentioned module documentations.
Link to sourcecode: server.js
The REST API will be started with the defined values from our .env
file.
const mongoose = require('mongoose');
const cors = require('cors');
const express = require('express');
const bodyParser = require('body-parser');
const handlebars = require('handlebars');
const request = require('request');
const fs = require('fs');
const app = express();
const dotenv = require('dotenv');
dotenv.config();
const production = process.env.PRODUCTION === 'true';
const port = process.env.PORT;
const FILE = require('./models/file');
/**********************
* Config / Preperation
**********************/
app.use(bodyParser.json({limit: '12mb', extended: true}));
app.use(bodyParser.urlencoded({limit: '12mb', extended: true}));
app.use(bodyParser.json());
/** Origins */
app.use((req, res, next) => {
const origin = req.headers.origin;
res.header('Access-Control-Allow-Origin', origin);
res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization');
res.header('Content-Type', 'application/json');
res.header('Access-Control-Allow-Methods', 'GET, PUT, POST, DELETE');
res.header('Access-Control-Allow-Credentials', true);
next();
});
...
/**********************
* Init server & connect to db
**********************/
...
app.listen(port, () => {
console.log(`Server (Production Mode: ${production}) is running on port ${port}...`);
});
All needed endpoints are listed in this file too. The main endpoint /
redirects to our team info page.
/**********************
* Routes
**********************/
/** Routes */
app.get('/file', (req, res) => {
...
});
app.post('/file', (req, res) => {
...
});
app.get('/file/:id', (req, res) => {
...
});
app.get(`/file/:id/download`, (req, res) => {
...
});
app.put('/file/:id', (req, res) => {
...
});
app.delete('/file/:id', (req, res) => {
...
});
/** Default */
app.get('/', (req, res) => {
res.redirect('https://lmf.software/info');
res.end();
});
Configuration and connection of our MongoDB. It connects in different ways, depends on the production
value. If production is true, it connects to a production database with defined values in .env
. If not, it connects without authorization to the defined local database.
...
mongoose.set('useNewUrlParser', true);
mongoose.set('useFindAndModify', false);
mongoose.set('useCreateIndex', true);
mongoose.set('useUnifiedTopology', true);
if(production) {
mongoose.connect(`mongodb://${process.env.DB_USER}:${process.env.DB_PASSWORD}@${process.env.DB_DOMAIN}:${process.env.DB_PORT}/${process.env.DB_TABLE}?authSource=admin`);
} else {
mongoose.connect(`mongodb://${process.env.DB_DOMAIN}:${process.env.DB_PORT}/${process.env.DB_TABLE}`);
}
...
Testcase ID | Feature ID | Test Description |
---|---|---|
TC.REST.001.F |
LF110 , LF100 , LF30
|
Black Box test. The test case verifies that the REST API GET calls work as documented in the SRS |
TC.REST.002.F |
LF110 , LF100 , LF30
|
Black Box test. The test case verifies that the REST API POST call works as documented in the SRS. |
TC.REST.003.F |
LF110 , LF100 , LF30
|
Black Box test. The test case verifies that the REST API DELETE call works as documented in the SRS. |
TC.REST.004.F |
LF110 , LF100 , LF30
|
Black Box test. The test case verifies that the REST API PUT call works as documented in the SRS. |
Test-ID | Pass/Fail | Testfailure Oberservation | Date | Tester |
---|---|---|---|---|
TC.REST.001.F | PASS | - | 19.5.2021 | Johannes Timter |
TC.REST.002.F | PASS | - | 19.5.2021 | Johannes Timter |
TC.REST.003.F | PASS | - | 19.5.2021 | Johannes Timter |
TC.REST.004.F | PASS | - | 19.5.2021 | Johannes Timter |
The REST API (Backend) module is the most important and powerful module of all. It handles a lot of tasks and contains the conversion for the .aml files.
All endpoints are documented in the swagger files. Other developers are able to understand them. Therefore, because of our well documented source code, other developers can edit or add new features to our backend.
The backend is expendable. Any new feature can be added very simply. The file module can be edited as well in future.
The source code of this module can be found here: aml-database-management-api
Testcase ID: | TC.REST.001.F |
---|---|
Testcase Name: | GET calls |
Requirement ID(s): |
LF110 , LF100 , LF30
|
Description: | The test case verifies that the REST API GET calls work as documented in the SRS |
Test Steps:
Step | Action | Expected Result |
---|---|---|
1 | Use the GUI to upload two files | Two files are uploaded and visible in the table in the home page |
2 | Open Postman and send the following GET request: localhost:3000/file | The two files that are present in the database are returned in the format as seen below, along with HTTP-Code 200. |
3 | Send the following GET request: localhost:3000/file/{mongoDBID}, where {mongoDBID} is the _id attribute of the first file that has been received in step 2 | Verify that only the first uploaded file is returned in the format below, along with HTTP-Code 200. |
{
"status": "success",
"data": {
"name": "TINF19C_AML_Library.aml",
"content": string
}
}
Testcase ID: | TC.REST.002.F |
---|---|
Testcase Name: | POST call |
Requirement ID(s): |
LF110 , LF100 , LF30
|
Description: | The test case verifies that the REST API POST call works as documented in the SRS |
Test Steps:
Step | Action | Expected Result |
---|---|---|
1 | Open Postman and send the following POST request: localhost:3000/file and use the Testdata below as body | Verify that you receive a JSON response containing "status": "success", as well as the just object that hast just been added |
2 | Send the following GET request: localhost:3000/file | Verify that the file is now present in the database |
Testdata:
{
"file": {
"base64": "data:application/xml;base64,ZnVlciBiYWxsdWY=",
"name": "test-file.xml",
"size": 560,
"type": "text/xml"
}
}
Testcase ID: | TC.REST.003.F |
---|---|
Testcase Name: | DELETE call |
Requirement ID(s): |
LF110 , LF100 , LF30
|
Description: | The test case verifies that the REST API DELETE call works as documented in the SRS |
Test Steps:
Step | Action | Expected Result |
---|---|---|
1 | Use the GUI to upload two files | Two files are uploaded and visible in the table in the home page |
2 | Open Postman and send the following GET request: localhost:3000/file. Remember the _id attribute of one of the files | One of the _id attributes is remembered. |
3 | Send the following DELETE request: localhost:3000/file/{mongoDBID}, where {mongoDBID} is the _id attribute of the first file that has been received in step 2. | You receive "status": "success" as well as the a response in the format below, along with HTTP-Code 200. |
2 | Send the following GET request: localhost:3000/file | Verify only the not deleted file is not returned anymore, along with HTTP-Code 200. |
{
"status": "success",
"data": {
"n": 1,
"ok": 1,
"deletedCount": 1
}
}
Testcase ID: | TC.REST.004.F |
---|---|
Testcase Name: | PUT call |
Requirement ID(s): |
LF110 , LF100 , LF30
|
Description: | The test case verifies that the REST API PUT call works as documented in the SRS |
Test Steps:
Step | Action | Expected Result |
---|---|---|
1 | Open Postman and send the following GET request: localhost:3000/file. Remember the _id attribute of one of the files | - |
2 | Send the following PUT request: localhost:3000/file/id={mongoDBID}, where {mongoDBID} is the _id attribute of the first file that has been received in step 1. Use the JSON testdata below as body of the PUT request. | You receive a JSON response containing "status": "success", as well as the object that hast just been manipulated (name and content) |
3 | Send the following GET request: localhost:3000/file | The content and name of the file have been changed according to the name and content of the testdata. |
Testdata:
{
"file": {
"content": "<?xml version=\"1.0\" encoding=\"utf-8\"?><Types xmlns=\"http://schemas.openxmlformats.org/package/2006/content-types\"><Default Extension=\"aml\" ContentType=\"model/vnd.automationml+xml\" /><Default Extension=\"rels\" ContentType=\"application/vnd.openxmlformats-package.relationships+xml\" /><Default Extension=\"xsd\" ContentType=\"text/xml\" /><Default Extension=\"png\" ContentType=\"image/png\" /><Default Extension=\"bmp\" ContentType=\"image/bmp\" /><Default Extension=\"edz\"ContentType=\"application/octet-stream\" /><Default Extension=\"xml\" ContentType=\"text/xml\" /></Types>",
"name": "New_Test_Name.xml"
}
}
© LMF.software - Jonas Bihr, Namid Marxen, Johannes Emanuel Timter & Nils-Christopher Wiesenauer
For any question regarding our software contact us on here on GitHub.
- Home
- 1. SRS (System Requirements Specification)
- 2. SAS (System Architecuture Specification)
- 3. MODs (Modul Documentations)
- 4. MM (Meeting Minutes)
- 5. User Manual
- 6. Systemtestplan
- 7. Systemtestreport