Build your web or mobile application as a set of microservices that can be independently tested, deployed, and owned by different application teams. Expose services as REST APIs and communicate with other microservices using APIs.
The most important requirements for a web or mobile app are:
- It must support a range of clients, such as browsers and mobile devices
- It must be secure
- It must deliver 24/7/365 availability
- It must scale to respond to spikes in demand
- It must handle low network latency
- It must have zero downtime when updated or modified
Oracle Cloud Infrastructure (OCI) provides scalable, secure, reliable, and highly performant infrastructure for the most demanding of web and mobile apps. This document presents the design principles to architect a web or mobile app, and reference architectures based on those principles.
Use lightweight open-source frameworks and mature programming languages
Use Graal Cloud Native or Helidon to build your app. Both provide features such as logging, telemetry, security, and configuration, as well as common patterns such as building REST APIs.
Use Java: a platform-independent, portable language with a rich set of libraries that is used by millions of developers to build scalable, resilient, and secure apps.
Build apps as services that communicate using APIs
Build your app as a set of microservices that can be independently tested, deployed, and owned by different app teams. Expose services as well-defined REST APIs and communicate with other services using those APIs. Use OCI API Gateway as the single point of entry for all clients, and then route API requests to the appropriate service.
Use OCI Service Mesh to simplify and secure communication between services hosted in your Oracle Container Engine for Kubernetes (OKE) cluster. OCI Service Mesh also allows you to observe all network traffic between your services via the metrics and logs emitted by its proxy component that runs as a sidecar on application pods.
Automate the build, testing, and deployment
Deliver code frequently and then deploy your app in a way that minimizes downtime. Use OCI DevOps to establish a consistent and automated way to develop, build, package, test, and deploy your apps. Use Oracle Cloud Infrastructure Resource Manager to reliably provision your infrastructure elements such as API Gateway, load balancers, databases, Kubernetes clusters, and other services.
Use fully managed services to eliminate complexity in app development, runtimes, and data management
Use fully managed services such as Oracle Container Engine for Kubernetes (OKE), Oracle Cloud Infrastructure Object Storage, and Oracle Autonomous Database: these services maximize availability and scalability to respond to the changing demands of your app. A fully managed service ensures your app availability and protects it if a failure occurs in the data center hosting your app’s infrastructure.
Keep app tier stateless
Where possible, keep the middle-tier components of your app stateless. If necessary, use Oracle Autonomous Database to store app state for consistency, durability, and fast recoverability.
Use converged databases with full featured support across all data
Your app might use data in a variety of formats such as tabular (relational), unstructured, XML, JSON, spatial, or graph. Traditionally, this variety required a different kind of database for each data format, for example a relational database for relational data, a document store for unstructured data, or a graph database for hierarchical linked data. However, the use of multiple databases often leads to additional operational complexity and data inconsistency. Instead, use a single multi-model Oracle Autonomous Database to store, index and search multiple types and formats of data.
Instrument end-to-end monitoring and tracing
It’s tempting for development teams to develop their own observability tools to gain visibility into the services and apps they own. Your app might contain hundreds of services, owned by different app and business teams. Instead of each team building its own tools, centralize the solution using the Oracle Cloud Observability and Management Platform: it monitors all layers of the entire stack to find and fix issues in your app.
Eliminate single point of failure through automated data replication and failure recovery
Your app must be resilient, recover from failures, and minimize downtime and data loss. Eliminate a single point of failure by implementing redundancy in the following ways:
- In OKE, set up node pools with a minimum of three nodes, with each node in a separate availability domain, in a multi-availability domain region.
- In a single availability domain region, setup node pools in OKE with a minimum of three nodes, with each node in a separate fault domain.
- Use a single public load balancer and multiple private load balancers with multiple ingress controllers for redundancy in OKE.
- Design a pilot disaster recovery topology to restart apps and restore workloads quickly in a standby region if a disaster strikes the primary region where your app is hosted.
- Configure your CI/CD pipeline to deploy your app to a standby region to recover from region failures.
- Replicate your block storage volumes across regions using block storage volume replication and object storage replication.
- Provision required infrastructure in the standby region using Oracle Cloud Infrastructure Resource Manager if the primary region fails.
- Set up your Oracle Autonomous Database for maximum availability using Autonomous Data Guard to minimize operational downtime and data loss.
Additionally, test for resiliency to see how your app behaves under abnormal conditions that occur intermittently. For example, you can adopt the Chaos Monkey framework for chaos testing. Also use throttling, circuit breakers, and retry mechanisms to implement a resilient app.
Implement a defense-in-depth approach to secure the app lifecycle
You should design your app with sufficient security to guard against attacks by malicious entities. Review your app, client-side code, and third-party code to check for suspicious behavior. Use filtering rules and set up DDoS protection using Web Application Firewall (WAF) to protect your app from unwanted traffic.
Store sensitive information such as passwords and authentication/authorization tokens in Oracle Cloud Infrastructure Vault. Set up encryption of Kubernetes secrets in etcd. Rotate and set short lifetimes on the certificates that your app uses to make it more difficult for an attacker to impersonate a trusted entity.
Follow the principle of least privilege to ensure that users and service accounts have only the minimal privilege necessary to perform their tasks. Control who has access to your app and its components using Oracle Cloud Infrastructure Identity and Access Management (IAM). Use multifactor authentication in IAM to enforce strong authentication for administrators to restrict access to your app and its components.
The following diagram illustrates this architecture.
The architecture has the following components:
- Web Application Firewall (WAF)
WAF protects apps from malicious and unwanted internet traffic. It can protect any internet-facing endpoint, providing consistent rule enforcement across all your apps.
- Oracle Cloud
Infrastructure API Gateway
OCI API Gateway is a fully managed regional API gateway service that provides protected RESTful API endpoints for OKE and any other service or endpoint running on Oracle Cloud Infrastructure. In this architecture, the requests are routed to a private load balancer which forwards the requests to a service running in OKE.
- Oracle Cloud Infrastructure Identity
and Access Management (OCI IAM)
OCI IAM provides robust multi-factor authentication, social login, self-registration for end-users, identity management, single sign-on, and identity governance for apps.
- Load balancer
The Load Balancing service provides automated traffic distribution from a single entry point to multiple servers reachable from your virtual cloud network, such as the OKE nodes of containerized microservices in the architecture
- Oracle Autonomous Database
Oracle Autonomous Database is a fully managed database environment that scales elastically, delivers fast query performance, and requires no database administration. You don't need to configure or manage any hardware or install any software.
- Object storage
Object Storage provides quick access to large amounts of structured and unstructured data of any content type, including database backups, analytic data, and rich content such as images and videos. Use standard storage for hot storage that you need to access quickly, immediately, and frequently. Use archive storage for cold storage that you retain for long periods of time and seldom or rarely access.
In this architecture, the media assets of the app are stored in Object Storage in a bucket of the standard storage class.
- Container Engine for Kubernetes (OKE)
OKE is a fully managed, scalable, and highly available service to deploy your containerized apps to the cloud. You specify the compute resources that your apps require, and OKE provisions them on OCI in an existing tenancy. Container Engine uses Kubernetes to automate the deployment, scaling, and management of containerized apps across clusters of hosts.
- Service mesh
Oracle Cloud Infrastructure (OCI) Service Mesh is an application infrastructure layer managed by OCI for service-to-service communication. It streamlines the development and deployment of cloud native apps by defining standards for observability, security, and traffic management. Service Mesh is implemented as an array of lightweight proxies that are deployed in the customers' pods alongside application code without requiring the application to be aware of them.
All the resources are deployed in a single availability domain in an OCI region. The tiers are isolated in separate subnets in a single virtual cloud network (VCN). Security Lists serve as firewalls to regulate the network traffic to and from the resources in each tier. A route table attached to each subnet contains rules to direct traffic to destinations outside the VCN.
Other alternative architectures such as Single-page Architecture, Progressive Web Applications (PWA), or JAMStack can be considered, but are not shown here.
The following diagram illustrates this alternate architecture.
Example Use Case
This use case describes a customer ordering system for a store that sells GPUs online.
The following diagram shows the architecture for this use case.
Traffic from the public internet is routed by the DNS service through a Web Application Firewall (WAF) to an Internet Gateway, which forwards the incoming requests to an Ingress (Nginx) microservice via the load balancer. The app is made up of a front-end service, an orders service, a messaging service, and an inventory service. All these services are containerized and are in the OKE cluster. Each of these services exposes its interfaces using REST APIs. Data is stored in Autonomous Databases.
The customer places an order for GPUs using the Front-End service from either a web app or an app on a mobile device. The Orders service and the Inventory Service communicate with each other using the NATS open source messaging service. The Orders service reads and writes order data in the Orders pluggable database (PDB). The Inventory service reads and writes inventory data in the Inventory PDB. The Orders service sends a notification using the Notifications service so that the customer can be informed of the order status via email or Slack. The customer can retrieve the order status from the front-end, which looks up the order using the REST API for the Orders service.
- Go to GitHub.
- Clone or download the repository to your local computer.
- Follow the instructions in the
This log lists significant changes:
|September 21, 2023
|Added a Deploy topic with a link to the sample application GitHub repository.
|July 11, 2023
|Added Graal Cloud Native and removed Micronaut from the first Design Principle.
|October 28, 2022
|March 24, 2022