Designing, building, and operating a custom two-sided online marketplace
Case Study: Taste Agent x Foxhound SystemsTaste Agent is a new venture, born from the creative incubator that is Relish Works—an innovation hub dedicated to investing in and cultivating groundbreaking products within the food service industry.
Following a successful collaboration in which Foxhound Systems played a pivotal role in developing a product and technology strategy for a restaurant-focused online marketplace, the Taste Agent team once again enlisted our expertise. The team entrusted us with the ambitious task of executing this vision by creating the marketplace platform.
The envisioned platform would serve as a marketplace to connect restaurant operators and social media influencers, facilitating innovative and compelling marketing and allow restaurants to tap into social media marketing to grow their customer base. The platform would facilitate meal bookings and allow the two parties to arrange meals for the purpose of influencers creating social media marketing content. For an initial release, the intended form factor would be a responsive web application designed for a mobile-first experience. The Taste Agent team established key technical criteria for the application, emphasizing exceptional performance across mobile devices under varying connectivity conditions, alongside a user interface designed for accessibility, conforming to the Web Content Accessibility Guidelines.
Director of Innovation, Relish Works
Project goals
There were several key goals defined at the outset of building the Taste Agent platform:
- Transformation of the product vision into a intuitive user experience and functional design.Our first objective was to build on the strategic foundation laid out in our preliminary engagement and translate the high-level product vision and strategic objectives of the Taste Agent team into a tangible user experience. We aimed to accurately model the envisioned feature set and user interface by creating detailed wireframes and functional specifications, which would clearly communicate the platform’s planned functionality to all stakeholders.
- Development of a completely custom, full-featured, production-grade software platform.The Taste Agent team decided against common approaches like heavily modifying WordPress or relying on no-code solutions, opting instead for a completely custom software build (you can read our thoughts on the topic in our article: Do “No-code” platforms reduce software development costs?). This approach was used to ensure maximum control over the user experience, application performance, and ability to scale over time, all while keeping infrastructure costs as low as possible in anticipation of growing platform traffic.
- An excellent, mobile-first experience in the form of an easy-to-use, highly performant, responsive web application.Given the preeminence of mobile engagement, our objective was to deliver an intuitive and responsive web application with excellent performance. Ensuring optimal functionality across mobile devices, especially during poor mobile connectivity, was paramount, to achieve the maximal level of application accessibility and user satisfaction.
- A plan for iterative development from the very beginning.Whereas many new software projects are developed as minimum viable products (MVPs) and are anticipated to be discarded, we recognized that this approach would not be suitable for this project. Understanding the complexity and ambition behind creating a marketplace, we opted for an iterative development strategy. Starting with a core set of features that address essential user needs, we planned for frequent improvements to the software based on direct user feedback post-launch, ensuring the platform evolves in alignment with its users’ desires and meets the business demands of the Taste Agent team.
- A timely launch that would synchronize with marketing initiatives.The development timeline was planned to align with marketing strategies and user acquisition efforts, setting a firm deadline for the initial release. This synchronization ensured that the platform would make its market debut exactly when anticipated, laying the groundwork for immediate user engagement and feedback.
Technology strategy
One of the biggest tasks our team had during this project was selecting approaches and tools to use to build the Taste Agent platform. Ultimately, our selections were based on the priorities laid out by the Taste Agent team considered against the various experiences we’ve had using numerous programming languages, frameworks, and platforms to build and operate software systems.
The top development priorities laid out by the Taste Agent team were as follows:
- Application performance: The application must be extremely responsive and all pages must load quickly.
- Web accessibility: The UI of the application must conform to Web Content Accessibility Guidelines (WCAG), targeting compliance level AA.
- Delivery timeline: The application be ready for launch at the designated deadline.
- Reliability and correctness: The development process must minimize defects in the application. All edge cases should be considered.
- Ease of maintenance: With iterative development expected shortly after launch, the application should be built in a way that is easy to maintain and lends itself to ongoing updates to the software.
In order to achieve these priorities, we made several key choices when building this project.
Employing server-side rendering for enhanced performance and simplicity
We opted to deliver HTML directly from the server using a server-side rendered (SSR) architecture, ensuring a straightforward and highly accessible navigation experience. This method contrasts with single-page applications (SPAs), which rely heavily on client-side JavaScript to dynamically update the UI without full page reloads. Our decision for SSR was driven by the desire to minimize business logic duplication, streamline content delivery, and enhance overall user experience by allowing the application servers to handle most of the processing.
This approach not only simplifies development by centralizing logic on the back end, but it also enhances responsiveness and accessibility for users by reducing CPU usage on the client’s browser. Given that most users will access the platform via mobile phone browsers—which typically have more limited performance capabilities than computers—leveraging the server-side capabilities to present a slim interface ensures a smoother experience without the complexity and overhead associated with SPAs. Our web accessibility target of compliance with WCAG level AA was made easier to achieve through our use of SSR, with traditional links and forms being used for navigation and interaction with the application.
For the limited number of cases in the application where a dynamic update to a page was necessary, we still typically deferred to the server. We used a JavaScript library called Turbo to perform partial page updates based on HTML blocks returned from the server. We also used Turbo Drive, a drop-in feature of the library that accelerates regular links and form submissions by turning document HTTP requests into XHR requests, significantly improving performance. For the cases where client-side updates were required (such as when modifying the default validation messages presented by forms without losing input focus), we used Turbo’s companion library, Stimulus.
We set a performance target of 100 milliseconds for user actions and page loads under good network conditions, which we believed to be achievable given the control we had over the rendering progress, as well as our high performance programming language and database selections.
Leveraging a best-in-class programming language & database combination
The server-side programming language we chose was Haskell, which we’ve both used and written about extensively in the past (see: Why Haskell is our first choice for building production software systems). Haskell is a statically-typed programming language with an extremely powerful type system. It gives developers the ability to identify many errors very quickly (maximizing the application’s reliability and correctness), and lending itself to rapid development (helping us achieve our intended delivery timeline). Haskell compiles to executables that are very fast, usually an order of magnitude faster than other languages commonly used for development, such as PHP, Ruby, or Python. This extra performance was doubly useful in a SSR application with all logic for both validation and rendering being performed by the application server.
We used PostgreSQL as our database, driven by our experience that relational databases are best-in-class at what they do, offering an unrivaled combination query flexibility, schema control, and performance. SQL databases, in our view, are the best choice for the overwhelming majority of applications, and PostgreSQL stands out as the leading open-source option. Its comprehensive feature set, thorough documentation, and wide compatibility make it an ideal choice for deployment across various cloud hosting environments, aligning perfectly with our project requirements and ensuring seamless operations for the Taste Agent platform.
Infrastructure optimized for seamless operations
A critical component of our partnership with Taste Agent involved not just the creation but also the ongoing maintenance and operation of the platform post-launch. To this end, the selection of the deployment environment and production infrastructure was a pivotal early decision. We chose Amazon Web Services (AWS) for its robust and scalable infrastructure, specifically utilizing Elastic Container Service (ECS), allowing us to deploy the application using containers but without managing containerization manually, for instance, through Docker.
Our deployment process is streamlined and fully automated, utilizing GitHub Actions for a seamless CI/CD pipeline. This setup employs the Nix package manager for its reproducible builds and Docker to creation the application image, which is pushed to the AWS Elastic Container Registry (ECR), from which it is automatically deployed to ECS by bringing the new versions online before tearing down the incumbent containers. This approach not only enhances the reliability and scalability of the platform but also ensures a smooth operational experience for the Taste Agent team and its users.
We lean heavily into other AWS services such as Cloudwatch for logging and alerts, Relational Database Service (RDS) for running our PostgreSQL database, Simple Email Service (SES) for sending emails, and S3 for file storage. We employ the principle of least privilege in our security configurations, deploying everything in a production AWS account with minimal access, aggressively restricting everything using security groups and eliminating public access where possible, such as to the database.