Skip to content

alaamjadi/WebDev_Hypermedia-4-Applications-Web-and-Multimedia

Repository files navigation

Hypermedia Applications - SophisticatedKids

Deployments

Deployment on Render

Deployment on Render

Swagger generated server

Overview

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.

Running the server

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.

Backend Documentation

General group information

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 - -

Specification

Web Architecture

Web Architecture

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.

Backend Structure

API

REST compliance

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.

OpenAPI Resource models

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.

Data model

In our OpenAPI data model we have:

  • Events
  • Person
  • Services

Here is the ER diagram of the model:

ER Diagram

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.

Logical Design

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.

Implementation

Tools used

The languages and frameworks that were used:

  • HTML / CSS / JavaScript
  • JSON / YAML
  • SQL
  • Bootstrap framework for frontend
  • Connect.js framework for backend

The technology stack and tools that were used:

  • Javascript on Node.js runtime using npm as the default package manager.
  • Swagger (OpenAPI) using Swagger 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 and pg Admin 4 query tool
  • Fetch API to retrieve data from API
  • Visual 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.

Environments

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.

Render Deployment

Project structure

.
└── 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

Discussion

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.

Other information

Task assignment

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%

Analysis of existing API

For our project we used the following OpenAPI:

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.

Learning outcome

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?

License

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.

Misc

Follow Mohammad: LinkedIn, Twitter

© SophisticatedKids 2020