DEV Community

Satyendra Pandey
Satyendra Pandey

Posted on

End-to-End System Design for a React + Java + Cosmos DB Application

In this guide, we’ll design a scalable React + Java application with Cosmos DB as the database. This setup is ideal for applications requiring high scalability, low latency, and multi-region availability. We'll cover everything from architecture to deployment, breaking it into actionable steps.


1. Planning and Requirement Analysis

Gather Requirements

  • Frontend Needs:
    • Dynamic UI.
    • Real-time updates.
    • Intuitive navigation.
  • Backend Needs:
    • Scalable APIs.
    • Complex data handling.
    • Secure data storage and processing.
  • Database Needs:
    • NoSQL structure for flexibility.
    • Low latency for global users.
    • Consistency levels for transactional operations.

Technology Stack

  • Frontend: React.js with TypeScript (optional), Redux for state management.
  • Backend: Java with Spring Boot.
  • Database: Azure Cosmos DB.
  • Communication: RESTful APIs.
  • Deployment: Docker + Kubernetes.

2. Architecture Design

High-Level Architecture

  • Frontend: React app for client-side rendering, API consumption, and dynamic UI.
  • Backend: Java Spring Boot for RESTful API development.
  • Database: Cosmos DB for highly available and partitioned data storage.
  • Communication: JSON-based REST APIs for interaction between the frontend and backend.

3. Frontend Development

Folder Structure

Organize the React project for scalability and maintainability:

src/
├── components/   # Reusable UI components
├── pages/        # Page-level components
├── hooks/        # Custom React hooks
├── context/      # Global state management using Context API
├── services/     # API calls
├── styles/       # CSS/SCSS files
├── App.js        # Root component
└── index.js      # Entry point
Enter fullscreen mode Exit fullscreen mode

Routing

Use react-router-dom for navigation:

import { BrowserRouter as Router, Routes, Route } from "react-router-dom";

function App() {
  return (
    <Router>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/users" element={<UserList />} />
      </Routes>
    </Router>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

State Management

Choose between Redux or Context API:

  • Use Redux for large applications needing centralized state management.
  • Use Context API for simpler state-sharing scenarios.

4. Backend Development

Spring Boot Setup

Set up a Spring Boot application with Maven or Gradle. Include the following dependencies:

<dependency>
    <groupId>com.azure.spring</groupId>
    <artifactId>spring-cloud-azure-starter-data-cosmos</artifactId>
</dependency>
Enter fullscreen mode Exit fullscreen mode

Project Structure

Organize your backend for scalability:

src/main/java/com/example/
├── controller/    # REST Controllers
├── service/       # Business logic
├── repository/    # Cosmos DB integration
├── model/         # Data models
└── application/   # Main application class
Enter fullscreen mode Exit fullscreen mode

Cosmos DB Configuration

Add the necessary configuration in application.properties:

spring.cloud.azure.cosmos.endpoint=<YOUR_COSMOS_DB_ENDPOINT>
spring.cloud.azure.cosmos.key=<YOUR_COSMOS_DB_KEY>
spring.cloud.azure.cosmos.database=<DATABASE_NAME>
spring.cloud.azure.cosmos.consistency-level=Session
Enter fullscreen mode Exit fullscreen mode

Define Models

Use annotations to map Java classes to Cosmos DB:

@Container(containerName = "users")
public class User {
    @Id
    private String id;
    private String name;
    private String email;

    // Getters and setters
}
Enter fullscreen mode Exit fullscreen mode

Repository

Create a repository interface for database operations:

@Repository
public interface UserRepository extends CosmosRepository<User, String> {}
Enter fullscreen mode Exit fullscreen mode

Service

Implement business logic in a service class:

@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;

    public List<User> getAllUsers() {
        return userRepository.findAll();
    }

    public User createUser(User user) {
        return userRepository.save(user);
    }
}
Enter fullscreen mode Exit fullscreen mode

Controller

Expose APIs to interact with the database:

@RestController
@RequestMapping("/api/users")
public class UserController {
    @Autowired
    private UserService userService;

    @GetMapping
    public List<User> getUsers() {
        return userService.getAllUsers();
    }

    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.createUser(user);
    }
}
Enter fullscreen mode Exit fullscreen mode

5. Database Design

Cosmos DB Features

  • Partitioning: Use a unique field like userId to optimize scalability.
  • Consistency Levels:
    • Use Session consistency for most scenarios.
    • Switch to Strong consistency for critical operations.
  • Indexing: Leverage Cosmos DB's automatic indexing for query optimization.

6. Integration

Connecting Frontend with Backend

Use Axios or Fetch in the React app:

import axios from "axios";

const API_URL = "http://localhost:8080/api/users";

export const fetchUsers = async () => {
  const response = await axios.get(API_URL);
  return response.data;
};

export const createUser = async (user) => {
  const response = await axios.post(API_URL, user);
  return response.data;
};
Enter fullscreen mode Exit fullscreen mode

Displaying Data in React

import React, { useState, useEffect } from "react";
import { fetchUsers, createUser } from "./services/userService";

function UserList() {
  const [users, setUsers] = useState([]);

  useEffect(() => {
    fetchUsers().then(setUsers);
  }, []);

  return (
    <div>
      <h1>User List</h1>
      <ul>
        {users.map((user) => (
          <li key={user.id}>{user.name}</li>
        ))}
      </ul>
    </div>
  );
}

export default UserList;
Enter fullscreen mode Exit fullscreen mode

7. Testing

Frontend Testing

  • Use Jest and React Testing Library for unit tests.
  • Write integration tests for API calls.

Backend Testing

  • Use JUnit and Mockito for unit tests.
  • Test database operations with embedded Cosmos DB:
  <dependency>
      <groupId>com.azure</groupId>
      <artifactId>cosmosdb-emulator</artifactId>
  </dependency>
Enter fullscreen mode Exit fullscreen mode

8. Deployment

Containerization with Docker

Create Dockerfiles for both frontend and backend:

  • Frontend Dockerfile:
  FROM node:16
  WORKDIR /app
  COPY . .
  RUN npm install
  RUN npm run build
  EXPOSE 3000
  CMD ["npm", "start"]
Enter fullscreen mode Exit fullscreen mode
  • Backend Dockerfile:
  FROM openjdk:17
  WORKDIR /app
  COPY target/*.jar app.jar
  EXPOSE 8080
  ENTRYPOINT ["java", "-jar", "app.jar"]
Enter fullscreen mode Exit fullscreen mode

Orchestration with Kubernetes

Deploy services using Kubernetes manifests:

  • Define Deployment and Service for frontend and backend.
  • Use ConfigMaps and Secrets for storing Cosmos DB credentials.

9. Observability

Logging

  • Use Logback for backend logging.
  • Use browser developer tools for frontend debugging.

Monitoring

  • Set up Prometheus and Grafana for backend monitoring.
  • Use Azure Monitor for Cosmos DB insights.

10. Best Practices

  • Use environment variables to store sensitive information.
  • Optimize API calls with pagination and filtering.
  • Follow proper error-handling practices.

This guide ensures a robust and scalable design for a React + Java + Cosmos DB application. You can adapt this architecture to fit specific use cases, ensuring maintainability and performance for your project.

Top comments (1)

Collapse
 
philip_zhang_854092d88473 profile image
Philip

This guide is like building a superhero team for your app—React as the sleek frontend, Java as the strong backend, and Cosmos DB as the reliable, speedy database sidekick!

To make API development even smoother, EchoAPI can be your secret weapon. It simplifies API testing, ensuring seamless integration between frontend and backend. Check out more on how EchoAPI can help example.com/!