How We Built It: DIRECT
DIRECT is DPG Media’s brand new online advertising platform — and serious competition for Facebook and Google in the Dutch and Flemish advertising market. Here, we have a quick look at the technology behind the platform.
DIRECT is a self-service environment where customers can create ads for all DPG Media’s online brands. It’s a flexible platform that allows advertisers to reach their target audiences through national, regional, and local brands. Have a look at DIRECT here.
So, how did we make it happen?
First of all, the backend of the application is built with Java and the frontend with ReactJS. Now let’s get into the details.
Serverless architecture with AWS
As we use chaos engineering for our Amazon Web Services (AWS) environments, we used an end-to-end serverless architecture for DIRECT’s backend system. This way, we guarantee tolerance and scalability — both provided out-of-the-box by AWS. Also, a serverless approach is a cost-efficient solution considering our workload of about 120 active users.
We reach our Lambda functions through an API gateway, and we secured them with Amazon Cognito’s authorizer.
Backend storage with Aurora
We decided to use Aurora for the backend storage because it’s up to five times faster than standard MySQL databases and three times faster than standard PostgreSQL databases. It provides the security, availability, and reliability of commercial databases at just 1/10th of the costs.
Amazon Aurora is fully managed by Amazon Relational Database Service (RDS), which automates time-consuming administration tasks like hardware provisioning, database setup, patching, and backups. For DIRECT, we used a new entry: RDS Proxy. RDS Proxy makes applications more scalable, more resilient to database failures, and more secure.
Asynchronous communication over synchronous communication
To achieve better availability and throughput of the entire system, we try to use asynchronous communication over synchronous; SQS + SNS helps us do so. Why SQS + SNS, you ask? Well, because our system is a distributed set of small services that need to exchange data. In asynchronous communication, if the service of the receiver fails, the sender can still send messages. The messages will be picked up when the consumer recovers.
This ability is advantageous in a microservices architecture because each service has its own lifecycle. A service could become unavailable or be replaced with a newer version at any given time. Asynchronous messaging can handle intermittent downtime. On the other hand, synchronous APIs require the downstream service to be available, or the operation fails. So, for asynchronous communication, we leverage SQS+SNS.
Frontend with Material UI and Redux
We use ReactJS for our frontend, and we’ve chosen Material UI for DIRECT’s components library, as it’s quite similar to the designs. This way, we don’t have to create UI components from scratch. Redux manages the application state, and we use Redux Persist for the persisted state.
We’ve decided to use Redux because our frontend stores a lot of data, so separating data and presentation layers allows easily control application re-renders and extends existing functionality. As for Redux Persist, one of its features saves the advertisement creation state up to three days. For this reason, we found Redux Persist the most popular and maintainable library for redux persistent state.
React Saga, Axios, Amplify, and Cognito
Everything related to side effects is managed by React Saga, which, compared to Redux Thunk, avoids callback hell and is easier to test. React Saga uses Axios for data fetching under the hood.
We use Amplify for secure user authorization and authentication because it’s based on the AWS infrastructure. For user management, we use Cognito.
How we test it
As for unit tests, we decided to use React Testing Library, which allows our tests to resemble the way users will use DIRECT instead of dealing with instances of rendered React components. The frontend app is hosted on S3 and served through Amazon CloudFront distribution (CDN).
Technology choices for flexibility and speed
Overall, we wanted to achieve flexibility and speed. We considered the availability of development tools, ready-made solutions, security requirements, the possibility of integration with other solutions, and the trends. That’s how we came up with this combination of technologies. That’s how we built DIRECT.