Skip to content

02. Architecture & Tech Stack

chrsBa edited this page May 10, 2024 · 9 revisions

Architecture

follow-request

AWS services

This section explains the key decisions regarding the used AWS services in our application.

AWS Lambda

Two Microservices. We decided to divide our backend into two microservices; the location-riddle-service and the user-service. The location-riddle-service covers all the game/guessing related functionalities where users can upload location riddles, see the ones of others, rate them, comment on them, and more. The user-service on the other hand covers the whole social media- and user account part. With this setup we ensure that high traffic on the game/guessing part won't affect the social media/user account part and vice verca. It further allows us to provision single parts of our application more specifically with additional resources when required.

Microservices deployed to AWS Lambda functions. We chose to deploy each of the two microservices to a separate AWS Lambda function. Lambda functions allow us to execute code at the exact moment of need without having to provision or manage servers. The key advantage of these functions is that they automatically scale with the amount of requests per microservices. This makes our setup very cost-efficient as we only pay for the actual traffic. ⁤⁤If there is no traffic, we incur no costs.

API Gateway

From the client's perspective, our Lambda setup and associated microservices are seamlessly integrated behind an API gateway. This gateway serves as a central point for all incoming requests and enables the combination of multiple AWS services, including Lambda functions. It provides a robust and scalable way to manage API traffic.

Amazon S3

Both the microservices are provided with their own S3 storage. Amazon S3 offers an easy integration with the other services and is rather common for cost-effective data storage. It is highly available and scalable. These are exactly the properties we need to efficiently store the images associated with the location riddles. Availability and scalability of the image storage is key to provide low latency in our application.

Third Party Services

Authorization

Auth0. Instead of implementing authorization ourselves, we decided to stick with Auth0. Through that solution, we make sure to follow the newest security standards while not having to deal with the complexity of implementing them. A big advantage is that we don't store any passwords or other sensitive data in our database as this is all covered by Auth0. Auth0 allows the easy use of single sign-on and social login (through google).

JSON Web Tokens. When a client communicates with the server, a JSON Web Token is required at all time. Such a token is obtained by the client after authenticating with Auth0. Our microservices then use this token for verifying the client's identity. Additionally, these tokens are able carry user specific claims like the username.

Software Development Tools

follow-request

Localstack

Localstack is used for emulating the whole AWS cloud architecture locally. The tool spins up a docker container which can then be used for spinning up further containers for the single services. This supports an efficient and independent development process.

Docker is a software for isolating applications with the help of container virtualization. Docker simplifies the deployment of applications because containers containing all the necessary packages can be easily transported and installed as files on different computers/servers.

Serverless

For defining, creating and connecting the AWS services, we use serverless. With serverless, one can deploy infrastructure and code with one single command. Thanks to this tool, our whole architecture is defined in more or less one YAML file. The advantage of it is that we can use the same file for deployment to different environments. The serverless-localstack plugin allows the seamless integration with Localstack, allowing an easier local development.

OpenAPI / Swagger

For automatically generating an API documentation, we are using OpenAPI. OpenAPI is a tool that generates a simple view for all Rest-Endpoints facilitating front-end developers' lives by showing what endpoints are exposed and what their expected values are. OpenAPI (formerly known as Swagger) nicely integrates with AWS powertools, thus requiring minimal additional effort by the developers for documentation.

Pydantic

We use Pydantic for data validation in the backend. Main arguments for this library was the easy integration with other tools like OpenAPI/Swagger and AWS powertools, but also the high performance.

Unittest

Python unittest is used for unit testing. The framework is widely known, lightweight and offers useful mocking capabilities like MagicMock.

Moto

Since our application relies heavily on AWS services, unit and integration tests can be challenging. Therefore, we used moto to mock the AWS services.

Playwright

For frontend testing, playwright is used. Playwright allows the easy and fast creation of end to end tests. We chose playwright over Selenium or Cypress because we found that authentication was easier to deal with compared to the other two frameworks. Further, playwright generates a useful report and comes with a test generator called "codegen" that eases the creation of test cases significantly.

Tech Stack

AWS Powertools (Python)

We decided to use python as our backend language since it allows the easy and quick creation of backend code and offers libraries such as the AWS powertools that facilitate the integration with AWS services. The AWS powertools allowed us the easy creation of our API endpoints.

No-SQL / DynamoDB

We chose a no-SQL database, namely DynamoDB, over the otherwise commonly used SQL database for its superior scalability and performance, especially crucial in our serverless architecture which demands high throughput and low latency. This is absolutely crucial for a social media app that shall work for millions of users. The flexible, schema-less data model supports our application's need for handling diverse, unstructured data types and seamlessly integrates with our other AWS services.

Ionic (TypeScript)

As our application leverages smartphone capabilities, such as camera access and location services, we decided to build a mobile application. To develop our mobile app across various platforms, we chose the Ionic framework. Ionic allows for native-like mobile development without having to learn platform-specific languages like Swift.

Angular (TypeScript)

Thanks to Ionic, we could select the well known Angular Framework for the frontend. Angular is one of the most common and feature rich frameworks when it comes to frontend (typescript) development. Furthermore, the team knowledge base about Angular is quiet well, what made the decision easy.