Building Modern Frontend Web Applications
Introduction
In today's rapidly evolving digital landscape, creating a seamless and efficient e-commerce experience is crucial for businesses looking to stay ahead of the competition.
This blog post aims to provide an in-depth exploration of how to craft a robust and user-friendly e-commerce platform by leveraging the combination of Meta Frameworks for frontend development and microservices for REST APIs. Additionally, we'll delve into the advantages of hosting these solutions on top of serverless infrastructure within the Microsoft Azure environment.
The e-commerce experience is composed of:
Page layout: Holds repeated files like Header and Footer, sets overall structure and style of the page.
Header: Displays important elements like logo, menu, and search bar, enabling easy navigation.
Shopping cart: Shows items added and their total price, allowing users to edit or remove items as needed.
Products: Displays a list or grid of products with options to filter, sort, and paginate for easy browsing.
Product Item: Displays a single product with all details, and allows users to add it to the cart or learn more.
Product vote: This lets users rate or review a product with emoji buttons, displaying the average rating and number of votes.
Application Characteristics
Before delving into the specifics of implementation, it is crucial to identify the key system attributes required for this e-commerce platform to ensure an optimal user experience and developer experience.
Frontend - Meta Framework
Modern JavaScript libraries have evolved, and now we see the emergence of Meta Frameworks that adopt a server-first approach to building frontend web applications.
A Meta Framework refers to a higher-level framework that builds on top of existing frontend frameworks or libraries. The purpose of a Meta Framework is to simplify and streamline the development process.
This may include:
Setting up a base project structure with pre-configured build and deployment tools
Implementing best practices for performance and maintainability
Use web fonts that are optimised for web delivery and avoid using too many fonts or font weights.
Use Image components and automatic image optimisation to resize, optimize, and serve images in modern formats.
Use analytics to monitor and improve the core web vitals of the pages.
Use code splitting and lazy loading to reduce the initial JavaScript bundle size and load only what is needed.
Integrating common features like routing and data fetching patterns by offering a better developer experience with a more guided and opinionated approach
Utilising server-side rendering and Server UI Components to enhance security by hiding sensitive information from the browser.
Backend - Microservices
An architectural style that develops a single application as a set of small, independently deployable services, loosely coupled, organised around business capabilities, and owned by small teams.
Avoid complexity by building on top of a microservices framework that helps developers to build, deploy, and manage microservices applications. A microservices framework can provide features such as service discovery, load balancing, fault tolerance, observability, security, and communication.
Hosting - Serverless
Serverless is a cloud computing model that abstracts away the servers and allows developers to deploy their code as functions or smaller applications that run on demand.
The serverless model extends beyond application code, as it can also be utilised for data storage, low-code integration, and monitoring services.
High-level Architecture
Having gained a better understanding of the e-commerce application characteristics, let's explore a high-level architecture for building this experience without focusing on specific technologies.
Frontend - Meta Framework
The development process for the e-commerce platform can be optimised by incorporating the following Meta Framework capabilities:
Layouts: Maintain UI state during navigation, prevent resource-intensive re-renders, and facilitate sophisticated routing patterns by allowing nested layouts and situating application code alongside the routes.
Server Components: Write components that run only on the server and send HTML to the client. This enables faster loading times, lower bandwidth usage, and better SEO. Server Components are different from server-side rendering (SSR) because they don’t generate HTML for the entire page at once. Instead, they stream chunks of HTML as they are rendered by Meta Framework on the server. This allows you to display parts of your page sooner, without waiting for all the data to load.
Data fetching: A key aspect of web development. In combination with Server Components, you can fetch data at the component level. This allows you to colocate data fetching logic with your UI and leverage streaming rendering.
Cache: Meta frameworks often include built-in caching mechanisms or support for native browser cache solutions to improve application performance. Caching in these frameworks generally works by storing frequently accessed or computationally expensive data in memory, so that subsequent requests for the same data can be served more quickly.
Error handling: Meta frameworks often provide built-in error handling mechanisms and support for custom error handling strategies to improve the user experience and simplify developer workflows. Error handling in these frameworks typically addresses both UI and API-related errors.
Backend - Microservices
Constructing the e-commerce APIs using a microservice framework enables the implementation of common microservices patterns, including service-to-service communication, state management, and pub/sub mechanisms for event handling.
Products API: This is a microservice that manages the products available for sale on the site. It exposes a REST API that allows clients to query, products. It uses a relational database to store product information, such as name, price, description, category, etc.
Product Vote API: This is a microservice that allows users to rate or review products. It exposes a REST API that allows clients to get or post votes for a given product. It uses a non-relational database to store the votes as documents, with fields such as product ID, user ID, emoji, and timestamp.
Order API: This is a microservice that handles the order placement process for the site. It exposes a REST API that allows clients to submit an order with the details of the products, quantities, shipping addresses, payment methods, etc. It uses a non-relational database to store the order information and its status. It also publishes events to a message broker when orders are placed or updated, so that other microservices can react to those changes.
Send an email: This is an event-based microservice that sends email notifications to users. It allows clients to send an email with a given subject, body, recipient, etc. It uses an external email service provider to send the actual emails. It subscribes to events from the Place order microservice to send order confirmation emails to the users when orders are placed.
Shopping cart: This is a microservice that manages the shopping cart functionality for the site. It exposes a REST API that allows clients to add, remove, or update items in the cart, as well as get the total price and quantity of the cart. It uses a cache to store the cart information as key-value pair, with fields such as user ID, product ID, quantity, etc.
Hosting- Serverless
A CDN can be used as an entry point for an application to improve its performance, scalability, and reliability.
A serverless container platform that automates the deployment, scaling, and management of containerised applications, allowing developers to focus on their application logic rather than infrastructure concerns. It abstracts away the underlying infrastructure, providing features like automatic scaling, load balancing, and rolling updates.
Container Registry that allows you to store and manage your private Docker container images and related artifacts securely and reliably.
Integration Service that allows you to create and run automated workflows with little to no code. The service must allow you to integrate and orchestrate your apps, data, services, and systems across cloud, on-premises, and hybrid environments.
A Storage service that allows you to store large amounts of unstructured data, such as images, videos, documents, etc
A relational or non-relational database for storing structured data, such as products, votes, orders, etc
Building on Microsoft Azure
Now, let's assemble all the building blocks to create the e-commerce experience using Azure's serverless infrastructure.
Before exploring the development process for frontend and backend components, let's first familiarise ourselves with Azure services and the advantages they bring.
Hosting - Azure Container Apps & supporting Azure services
App Hosting services:
Azure Front Door is a globally distributed, scalable, and secure entry point for web applications. It provides advanced traffic routing, load balancing, and application acceleration through features like SSL offloading, URL-based routing, and custom domain support. Azure Front Door enhances application performance by leveraging its anycast protocol, caching static content at edge locations, and automatically routing users to the nearest and most performant backend.
Azure Container Apps is a serverless platform for deploying and scaling containerised applications, supporting microservices architecture, and event-driven programming. It abstracts away infrastructure management, providing automatic scaling, patching, and simplified deployment pipelines.
Azure Container Registry is a serverless, private Docker container registry service that stores and manages container images, making it easy to deploy and run containerised applications.
Integration Services:
Azure Logic Apps enables users to design, build, and run workflows that integrate with various services, APIs, and systems. It provides a visual designer for creating complex, customisable workflows, with support for both cloud and on-premises data and services.
Azure Service Bus is a fully managed messaging service that enables communication between decoupled components of a distributed application.
Storage Services:
Azure Blob Storage is a scalable, cost-effective cloud storage solution for unstructured data like images, videos, documents, and logs. It provides high availability, durability, and redundancy, making it suitable for a wide range of applications.
Azure Redis Cache is a managed, in-memory data store based on the popular open-source Redis. It offers high-performance caching and data access for applications, improving response times and reducing the load on backend systems.
Azure Cosmos DB is a globally distributed, multi-model database service designed for use with applications requiring low latency, high throughput, and elastic scaling. It supports popular NoSQL data models like document, key-value, graph, and column-family, and offers built-in support for tunable consistency levels.
Azure PostgreSQL is a fully managed relational database service based on the open-source PostgreSQL engine. It offers features like high availability, automatic backups, and scalability.
Frontend - Next.js 13 a Meta Framework
There are many Meta Frameworks like Remix, Nuxt, SvelteKit and Astro for building web applications.
This e-commerce experience is built on Next.js 13 which is a popular framework for building React-based web applications. It offers features like server-side rendering (SSR), and automatic code-splitting, which help create fast, optimised, and SEO-friendly web applications.
Next.js also provides a flexing hosting model which can be containerised and hosted on Azure Container Apps.
Hosting on Azure Container Apps enables React Server Components to coexist seamlessly with supporting microservices. This means the Server UI Components Products, Product Item, and Product Vote can now communicate directly with microservices in a faster, highly secure, and scalable manner.
Backend - Dapr for Microservices
Dapr (Distributed Application Runtime) is an open-source, event-driven runtime that simplifies the development of microservices and distributed applications. It provides a set of building blocks to address common challenges in building cloud-native applications, such as state management, pub/sub messaging, and service invocation, enabling developers to focus on their application logic.
Azure Container Apps integrates Dapr as an optional feature for building microservices applications.
We can take advantage of the service-to-service invocation feature to enable communication between React Server Components and microservices without having to leave the internal network boundary.
The Order API leverages the pub/sub features on Dapr to publish events to a message broker (Azure Service Bus) when orders are placed or updated so that other microservices can react to those changes. In this example, Azure Logic App identifies the occurrence of an event and proceeds to send an email confirmation for the order.
Conclusion
Meta Frameworks have made frontend development fun with support for layouts, nested routing, server components, data fetching and mutation, error handling, and so much more.
Building on Azure Container Apps, you can create serverless applications with containers and integrate them with your preferred programming language and frameworks. When you combine Meta Framework features with frameworks like Dapr, it enables your microservices and server-based UI components to coexist effortlessly. As a result, your UI components can communicate directly with microservices within a secure network boundary, leading to faster, more secure, and more scalable service-to-service communications.
The demo for this blog can be found here and I will release the repo as part of the follow-up blog.
Subscribe to my newsletter
Read articles from Thivy Ruthra directly inside your inbox. Subscribe to the newsletter, and don't miss out.
Written by