There is a famous quote by American racer Bobby Unser “Success is where preparation and opportunity meet." And I think it perfectly applies to every successful software development project that, in a nutshell, is a customer with a great business idea (opportunity) meeting the development team with extensive knowledge, skills, and experience (preparation).
It would not be an exaggeration to say that Impressit’s cooperation with ESOOKO was exactly that — a story of successful mobile app development that both parties are very satisfied with.
ESOOKO was founded by two young men, Jacob and Angus, in the UK. It was a fashion marketplace that allowed its customers to support environmental initiatives while shopping. With each purchased item, the buyer paid a small fee that went to one of the three eco-initiatives. We met them through our friend Warren who was creating a design for their new app.
At that moment, ESOOKO was a web platform with several thousands of registered users. Basically, they wanted us to create a mobile app from scratch and migrate all the users from the web platform there. Besides that, ESOOKO had ambitious goals and grand plans. In 2021, they planned to attract around 100,000 users to the new mobile app. This way, their main requirement was for the application to be stable, scalable, and flexible. For the first time, we met in late August – early September 2020 and discussed their ideas, needs, and requirements. We made an estimation for the project so they came back to us in November, when Warren’s design was in the final stage. After we had prepared the final proposal, ESOOKO made a decision to start the development of their project with Impressit.
The project was divided into three phases: Planning phase, Development phase, and Delivery phase. The preliminary estimate of the project duration was approximately 7 months. And I will put the spoiler right away here — we managed to finish almost everything and went maybe a little over these 7 months due to the small changes in the scope of work. We delivered on our commitments knowing how important a timely launch was to ESOOKO and how bad delays might affect their plans.
During the first phase, our project manager Rob and I were the ones actively working on the ESOOKO project. Natalia, who became the main backend developer, Volodymyr, who took on frontend development responsibilities, a QA manager, another frontend developer, and a DevOps joined us for the next two phases.
The number of people involved in the project was constantly changing, depending on the number and type of tasks on the project. We try to always be flexible and quickly find developers to strengthen the team if we see that at a certain moment, the project will really benefit from it. The maximum number of people involved in this project was eight.
I should also mention that Angus and Jacob were in touch with Robert, took an active part in the project as product owners, and joined in planning sessions, daily meetings, and demo presentations.
For this project, we chose PHP. Firstly, because we had certain experience with it before, and secondly because Node was just starting to gain momentum and PHP with the Symfony framework at that time looked like a simpler and more stable solution, with which the customer would not have problems later. Among other technologies used are Redis, AWS, Elasticsearch, and Stripe.
Because the team was relatively small, and the project duration was estimated to be 7–8 months, we chose the Scrum methodology. During the first phase, Rob was preparing everything needed for successful project management and setting up Jira.
Scrum perfectly aligned with the way we strived to organize our project. We worked in sprints and held all the necessary ceremonies: plannings, dailies, reviews, and even had a retrospective or two. Scrum definitely helped us not only to keep the development pace but also to adjust to small changes in the work scope and show constant progress to the ESOOKO team.
As I've mentioned before, we began our cooperation in November with a planning stage, which lasted for four months. While Rob was making his PM magic, I worked on an architecture proposal and set up the local environment and AWS account. Long story short, it was a month of technical preparations so everyone who would join the project in the next stages was able to jump to work right away.
During this stage, we also had to make a crucial decision — Android, iOS, or cross-platform. Initially, ESOOKO was considering cross-platform development as this might attract more customers. However, they had their doubts and turned to us for expert advice. We conducted a small research, considering the given requirements, presented them with a list of pros and cons for each, and the final decision was made in favor of native development for iOS. It was a more convenient and flexible option. The development of an Android version of an application was planned for later.
Considering ESOOKO’s requirements and vision for the future, we decided to use microservices and the backend for the frontend approach with a BFF server, which was the entry point to the application, and when the application wanted to extract or write something to the database, it first made a request to the BFF.
Each of the microservices was represented as an API with a number of endpoints and was completely protected by the Amazon firewall level. They could not be reached from the outside, only the BFF could make a request to them, as well as the database and all the data – we made sure everything was protected. Moreover, BFF included the main scenarios for the application’s performance on frontend.
One of the features that the customers wanted to see in the app was an admin panel for them to check the app statistics. Because we chose microservices architecture with a sudo endpoint, we could just combine it with a frontend part with simple UI components we had. Through this admin panel, they could see the general app stats such as the number of users, the number of uploaded items, and so on.
We use microservices and Domain-Driven Design (DDD) for flexibility and scalability. Our Front API server handles request validation and user pre-authentication. We have eight microservices: User, Profile, Token, Item, Notification, Messenger, Order and Payment. All services work with MySQL, with isolated tables. Some use ElasticSearch for filtering and searching, and Payment works with Stripe. Notification uses Pusher for real-time notifications. Token and Front server use Redis for API tokens.
As we chose the microservice architectural pattern, we understood that it needed to be well-organized. Domain Driven Design integrates very well with the microservice architecture.
I should mention also that we chose onion architecture for this project which is often used in the DDD approach. It consists of 4 levels: application level, domain level, infrastructure level, and UI level. In this case, DDD was mainly responsible for the domain level, where we describe our models, aggregation root entity, and value objects. This helped us to make the app more maintainable and more scalable as well as simplified the testing process.
Moreover, pure DDD works with CQRS (Common query responsibility segregation) and event sourcing, which are very complicated and usually used only on big enterprise projects. We used a simplified DDD approach not using the complete separation of databases, not using event sourcing, just simplifying so that everything is conveniently separated into domains and subdomains, if needed. A simplified DDD approach results in an application that scales well and which can then, if desired, be translated into a full-fledged DDD, simply by including event sourcing and separate databases, for instance.
In ESOOKO’s particular case, the alternatives were either using DDD or not using DDD. If we opted not to use DDD, a monolithic application would be the way to go as we usually choose it for startups and small projects. Projects with microservices architecture and a DDD approach usually take more time and are more expensive. So, in most cases, monolithic architecture works for small and simple projects. If we mixed everything that needed to be done for ESOOKO into one big monolith, without using DDD, onion architecture, and various interesting architectural approaches, it would be difficult for us. In several months, we would have a lot of code in the files, and the structure would grow very much. That simply would be the wrong decision.
Choosing and integrating the payment system is perhaps one of the most important tasks in the development of a marketplace. At first, ESOOKO really wanted to integrate PayPal while also considering Stripe as an option.
Our team preferred Stripe which has extensive documentation, great community and support as well as a very pleasant pricing and discount policy for entrepreneurs. On the other hand, at that time, PayPal’s marketplace solution was under maintenance with no exact date of completion of work.
Thus, the decision was made to proceed with Stripe and use their platform Stripe Connect to integrate it into the ESOOKO app. This process was an interesting experience with a number of challenges and creative solutions. You can find out more about this process in the separate article.
The Checkout process begins when the user opens the Checkout screen, prompting the application to send a Buy request to the backend. On the backend, specific seller-related items are extracted from the cart, validated, locked, and processed to calculate the Total needed for the order. Once these steps are complete, the backend requests the Order service to create and automatically confirm a Stripe Payment Intent. It's worth noting that in cases requiring additional verification, the backend responds with a Client Secret key to the application, and the frontend handles the confirmation similarly to a Setup Intent.
After we integrated the payment system, we finally started preparing the production environment. And since we generally worked with AWS, it was decided to create a separate AWS account for the production environment so as not to mix the two infrastructures.
At that point, a DevOps specialist joined our team to set up pipelines for us. We configured the pipelines on GitLab in such a way that they would deploy our entire solution on AWS with a simple push of a button.
The main basic foundation of the infrastructure was ECR (Elastic Container Registry.) It allowed each microservice to be isolated in a separate container and deployed independently. When we did something new in a specific microservice, we created a new container and pushed it into the same ECR. Also, we created a separate cluster on Fargate with Amazon ECS (Elastic Container Service). This AWS technology essentially provides virtual power to run a container inside.
Generally speaking, our DevOps set up all these connections. He set up GitLab pipelines, which automatically, after the final decision to the main branch or with a click, were able to deploy everything to ECR.
We went public by the end of May and by that point, we were done with the backend development. Another frontend developer joined the team so we could finish the last few frontend tasks. In June, we still did some testing and minor improvements, but the app was stable and was out just as it was intended. And then we had the final release at the beginning of July. It was a fully functional app with infrastructure and detailed documentation.
Wisely organized and executed development allowed ESOOKO to implement plans for the marketing and promotion of their product as it was initially planned. They received a final product that met their requirements and expectations both in terms of functionality and performance.
As I mentioned at the beginning of the article, ESOOKO had a web platform with approximately five thousand users they wanted to migrate to the new mobile app.
The problem was that ESOOKO did not have direct access to the said web platform. Therefore, we could neither get to the server nor see what kind of data structure they have there. We requested access to the data to prepare the migration script. And then we waited for about 2 months for the company that had access to the ESOOKO’s web platform to provide us with some information.
Spoiler alert: at the end of the day, we abandoned the idea of migrating the user base. When our team finally got access to that platform’s system, we discovered that it contained nearly 300 different tables. Trying to work around that would disrupt our development process and definitely would delay the delivery of the final product. Therefore, it was decided to simply send all the existing users emails with the invitation to the new platform.
In a short span of a few months, the app gained around 20 thousand users. One day, ESOOKO launched a marketing campaign with some fashion bloggers. This campaign had amazing results, and at some point, the traffic grew so much the system began to fail. Please, mind, that we did not turn on autoscaling. Of course, we performed stress testing before deployment; however, it was for several hundred requests per minute. But this time, the numbers for requests for user service (which was responsible for the registration, logging in, and user accounts) and product service (which was responsible for all the actions with the items) were staggering, and the system was lagging heavily.
When we increased the number of resources that were used, the application just started to perform brilliantly, despite the fact that we had 12 microservices. This showed the system met our expectations, and that our efforts were not in vain. The user reviews were all positive.
For a few months, we supported the application, while also fixing the minor bugs and adding finishing touches to the frontend. After that, the application worked autonomously with no issues.
After less than two months on the market, in August 2021, Apple included the ESOOKO app in the list of AppStore’s new favorite apps. Being regarded as one of the ‘latest and greatest must-download apps’ was both an honor and proof that Impressit did a great job turning ESOOKO’s idea into a brilliant product.
But that’s not all — by the end of December, ESOOKO planted their first 1,000 trees and was mentioned by AppStore once more, in their year roundup as one of the great apps of 2021.
In our turn, Impressit was glad to be a part of this project and take part in ESOOKO’s journey.
Looking back now, I am proud of the ESOOKO development process. Correctly chosen project management practices and a successful approach to development allowed us to deliver the project on time. We met the agreed deadlines and, at the same time, did not sacrifice quality.
I am proud and happy that our team managed to bring so much value to the customer while also considering their needs, desires, and future plans.
Andriy Lekh
Other articles