This server was generated by the swagger-codegen project. By using the OpenAPI-Spec from a remote server, you can easily generate a server stub.
To run the server, run:
npm start
To view the Swagger UI interface:
open http://localhost:8080/docs
This project leverages the mega-awesome swagger-tools middleware which does most all the work.
Course: Hypermedia Applications (Web and Multimedia)
Group Name: SophisticatedKids
Member | Role | First name | Last Name | Person Code | Email address |
---|---|---|---|---|---|
1 | Administrator | Mohammad | Ala Amjadi | - | - |
2 | Member | Aysa | Javadzad | - | - |
3 | Member | Najib | El Guertit | - | - |
Our web application's architecture is built on three layers:
- Data layer
- Application
- Presentation
The data layer is implemented through the PostgreSQL
database, which contains the application data.
The application layer is implemented through the backend software which exposes a REST API (under the endpoint /api
) to the public in order to enable the interaction with frontend using a Node.js
server. This layer contains three compnents, openAPI gateway, controllers, and services. The openAPI gateway and controllers together become as API layer which connects to the data layer using services and makes the application layer to become an interface between data later and presentation layer. The services interacts with the data layer to retrieve the data from database using a SQL query builder for Postgress named knex
provided by node package manager (npm).
The presentation layer is implemented through the frontend component. This component contains the logic to load asynchronously data as JSON
objects from the application layaer with a REST API and render the web pages on client side from presenetation layer using HTML
/CSS
/JavaScript
. For the frontend part Bootstrap 4
framework has been used to satisfy responsiveness.
We'll approached REST principles by targeting their main points, by explaining if and why we have followed those principles.
- Uniform Interface: this is fundamental to the REST Api design and we did our best to follow this principle. Our interface is resource based, the client has enough information to customize the sources where he has the permissions just from their representation, the messages are self descriptive,and we use HATEOAS (Hypermedia as the Engine of Application State).
- Client-Server: the client application and server application are totally able to evolve separately without any dependency on each other.
- Stateless: we obviously could make our application stateless, as session management was not requested.
- Layered System: the system is layered, as the server is deployed in a place other than the one where the postgres server is.
- Code on demand: we are actually always sending the static representations of our resources in the form of JSON, so this point is not relevant.
The required HTTP status codes were introduced in the REST API. We used an OpenAPI Specification (formerly Swagger Specification) in order to build an API description. We chose to have three main resource models that comply with the REST principles. Each resource has a unique identifier and can be retrieved explicitly using a "GET" command with the URI of the resource. A group of all resources can also be retrieved if the ID is not specified. We also used nested paths in order to retrieve related resources of a specific resource. For example, in the nested path /api/events/eventId/person
, we retrieved the list of persons who are a contact for an event with a specific eventId.
We kept everything simple, in order to have a more understendable model: the most part of our resourcesare were described by a key-value. Event dates and urls are saved throught strings. Most of the tables in the database store a unique identifier for every row, such as the Event/Service/Person ID.
The Resources are introduced in the following models which are related to the data models.
Events
Person
Services
For each resource we have the following standard GET methods
/api/{resource}/
/api/{resource}/{resourceId}
/api/{resource}/{resourceId}/connection1
/api/{resource}/{resourceId}/connection2
To handle the events filteration more efficiently we have introduced the following endpoint to retrieve event data by specifying their year and month.
/api/Events/Y/{Year}/M/{Month}
A group of all resources can also be retrieved if the ID is not specified. This can happen by using the /api/{resource}/
endpoint which returns an array of objects.
Each resource has a unique identifier which can be used with /api/{resource}/{resourceId}
endpoint to retrieve an explicit single resource item.
The connection1
and connection2
are the related resources that have a connection to the main resource which we use them to retrieve a subdata of their resources. For example /api/Events/{eventId}/Services
and /api/Events/{eventId}/Person
return an array of objects which are the related services and persons for a specific event. Another example could be /api/Services/{serviceId}/Events
and /api/Services/{serviceId}/Person
return an array of objects which are the related events and persons for a specific service.
In our OpenAPI data model we have:
- Events
- Person
- Services
Here is the ER diagram of the model:
The data layer and OpenAPI data model mapping is as follows:
OpenAPI Model | Data Layer |
---|---|
Events | Events |
Person | Person |
Services | Services |
No mapping (*) | Involve |
No mapping (*) | Present |
*: There were no direct mapping for Involve
and Present
tables since we created them by joining Person
and Services
tables together to get the Involve
table and also we joined Events
and Services
tables to get the Present
table.
NOTE: To connect the DB to the application, the
DATABASE_URL
key along with a value with the following format:postgres://USER:PASSWORD@HOST:PORT/DATABASE
should be specified in the environment variables of your cloud service.
The languages and frameworks that were used:
HTML
/CSS
/JavaScript
JSON
/YAML
SQL
Bootstrap
framework for frontendConnect.js
framework for backend
The technology stack and tools that were used:
Javascript
onNode.js
runtime usingnpm
as the default package manager.Swagger
(OpenAPI) usingSwagger Editor
(link) to generate and manage the server and the specification.Postman
for testing the API completly but we could also use Swagger inspector.Postgres
RDBMS andpg Admin 4
query toolFetch API
to retrieve data from APIVisual Studio Code
as a text editor embedded with linter to analyzes source code in order to flag programming errors, bugs, stylistic errors, and suspicious constructs.Git Bash
to reduce the confusion while using git repository by having colorful texts in CLI.Developer tools
embedded in Google chrome.
The node packages that were used:
js-yaml
is an implementation of YAML, a human-friendly data serialization language.swagger-tools
provides various tools for integrating and interacting with Swagger.serve-static
creates a new middleware function to serve files from within a given root directory. The file to serve will be determined by combining req.url with the provided root directory.connect
is an extensible HTTP server framework for node using "plugins" known as middleware.connect-redirection
is a middleware which adds a redirect function to the response.pg
node-postgres (aka pg) is a collection of Node.js modules for interfacing with PostgreSQL database.knex.js
is a SQL query builder for Postgres designed to be flexible, portable, and easy to use.
We used localhost testing environment for development. The environment composed by Node.js, Postgres and PGAdmin.
The production environment is hosted on Render. They provide a ready to use Postgres database and a NodeJS environment.
.
└── api
└── swagger.yaml # openAPI specification
└── controllers # API controllers
└── other/ # database initilization and data
└── public # static files served to the browser
├── assets/ # all website assets css/img/js
├── backend/ # all project delivery materials
├── pages/ # static pages of website
└── index.html # main starting page (home-page)
├── app.json # manifest format
├── index.js # app startup for node server
├── package.json # npm project dependencies
└── README.md # git documentation
How did you make sure your web application adheres to the provided OpenAPI specification? Which method did you use to test all APIs endpoints against the expected response?
We started from the OpenAPI specification to build the project, and during the process of building the web application, we changed and manipulated the specification in order to keep it updated and coherent with the state of our project. Almost every API operation is used from the front end side, and if not, either the operation can be used to add data to the database (We did not implement since it was not neccessary) or to supply data to other operations. Moreover, we did not have an extra endpoints that were not used, however the parent edpoints or combinations of endpoints can be used in the front-end to expand the application anytime.
For testing all APIs endpoints against expected response, we used Postman
. We could also use Swagger inspector.
Why do you think your web application adheres to common practices to partition the web application (static assets vs. application data)
The application strictly separate the frontend (HTML/CSS/JS) from the backend components (Data in remote DB) and they communicate only through the REST API using HTTP requests via /api/{resource}
paths. The source of backend is placed in the project root /
, while the source of frontend is placed under /public
directory and is addressed with serve-static in the web application. However, as it was not required for all the pages to be dynamic there are some pages such as Home/Association/Contact that use static data.
Describe synthetically why and how did you manage session state, what are the state change triggering actions (e.g., POST to login etc..).
We skipped this part since we did not need to handle sessions and it was not required and neccessary for our application.
Which technology did you use (relational or a no-SQL database) for managing the data model?
We used a relation database called PostgreSQL. The relation model fits good in a project were you have to manage various associations between different models.
Member | Usability | Front-end | OpenAPI | Backend | User Testing (Bonus) |
---|---|---|---|---|---|
Mohammad Ala Amjadi | 40% | 50% | 70% | 90% | 10% |
Aysa Javadzad | 30% | 40% | 20% | 10% | 90% |
Najib El Guertit | 30% | 10% | 10% | 0% | 0% |
For our project we used the following OpenAPI:
- The example showed in class of dataatwork.org.
- The simple and basic example by swagger.io of a Pet Store.
- As advised in class we found these two OpenAPIs on APIs Guru: Personalizer Client API and Listen API: Podcast Search & Directory.
- There is also an other more extended and detailed API that is the Google Books API.
By looking at those examples we got a better idea about OpenAPI. We constantly looked at the OpenAPI Specification documentation during the development phase. We started with presenting our first version of swagger. Each time that we had a tutroing sessions we got a feedback which we took into account. When we tried to develope the swagger services we realized that we have to change a lot. So we generated many swagger versions. In the end we reached the event page, in order to handle some features (Event filteration) there we were forced to change the swagger again and we have decided to have an extra endpoint for events to retrieve event data by specifying their year and month for the events page, in case the events were scaling up in our website. At the end, by testing the API over and over and going forward with the developement we were sure that our final specification became a fit to our application.
In this project anonymous member and Mohammad both have learned how to create an OpenAPI Specification and how to implement it using a Node.js server.
- Anonymous member improved her HTML, CSS and SQL skills while she learned more JavaScript specially using Fetch API and Promisses.
- Mohammad improved his JavaScript skills while he learned about DOM, Bootstrap and SQL from scratch. Mohamamd has plan to develope and implement simillar projects in the future.
Some unanswered questions are:
- In our project we have inserted into the db a small number of data. How scalability and performance go with bigger data? Are there other methods to implement a more performant version?
- We used Render to provide our application. How can we migrate to another PasS (Platform as a Service) for example GCP (Google Cloud Platform.) What measurements we have to take into account to choose the best platform solution?
- How should we handle the security part of ou application? Should we change our source code or there are other ways to handle the security more smoothly?
- Are there any better technology solutions beside the one we had used?
This resource can be used freely if integrated or build upon in personal projects such as websites, web apps and web templates intended for personal or academic purposes only. It is not allowed to take the resource "as-is" and sell it, redistribute, re-publish it, or sell "pluginized" versions of it. Any built using this resource should have a visible mention and link to the original work. Always consider the licenses of all included libraries, scripts and images used.