Quillr implements a gRPC-based microservices architecture using NestJS, Prisma ORM, Docker, and Kubernetes. The system consists of two microservices: Author Service and Book Service, which interact with each other via gRPC. The system uses PostgreSQL for data storage and Docker for containerization. Kubernetes is used to orchestrate the deployment and scaling of the microservices.
It consists of two services: Author Service and Book Service. Both of these services expose different gRPC methods to manage their respective entities.
π οΈ Architecture
The Author Service is responsible for managing CRUD operations for authors. It interacts with a PostgreSQL database, where each author has an id, name, email, and createdAt field.
-
Schema:
id: UUID (Primary Key)name: Stringemail: String (Unique)createdAt: DateTime
-
gRPC Methods:
createAuthor: Create a new author.getAuthor: Retrieve an author byid.updateAuthor: Update an existing author.deleteAuthor: Delete an author byid.listAuthors: List all authors.
The Book Service is responsible for managing CRUD operations for books. A book is associated with an author using a foreign key (authorId), which references the Author.id. The service includes operations like creating, updating, and deleting books, as well as listing books and retrieving books by a specific author.
-
Schema:
id: UUID (Primary Key)title: StringauthorId: UUID (Foreign Key referencingAuthor.id)publishedYear: IntcreatedAt: DateTime
-
gRPC Methods:
createBook: Create a new book.getBook: Retrieve a book byid.updateBook: Update an existing book.deleteBook: Delete a book byid.listBooks: List all books.getBooksByAuthor: Retrieve all books for a given author using a gRPC call to the Author Service.
We will use PostgreSQL as the database for both services. The PostgreSQL database will be containerized and used to persist data for authors and books. The Prisma ORM will be used to define the database schema and handle queries, migrations, and schema updates.
The Book Service will interact with the Author Service via gRPC to ensure that the author exists before creating or updating a book. The communication between services will be defined by .proto files, which specify the methods, request/response types, and data structures.
The system will be containerized using Docker. Below are the essential files to make sure the services can be containerized and communicate with each other.
The docker-compose.yml file defines the services, including the PostgreSQL database, the Author Service, and the Book Service. It ensures all services can communicate within the same Docker network.
version: '3.8'
services:
postgres:
image: postgres:15
container_name: postgres_db
restart: always
environment:
POSTGRES_USER: postgres
POSTGRES_PASSWORD: password
POSTGRES_DB: author-service
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init.sql:/docker-entrypoint-initdb.d/init.sql # SQL script to create the second DB
author-service:
image: author-service-image
container_name: author_service
restart: always
environment:
DATABASE_URL: postgres://postgres:password@postgres:5432/author-service
depends_on:
- postgres
ports:
- "50051:50051"
book-service:
image: book-service-image
container_name: book_service
restart: always
environment:
DB_URL: postgres://postgres:password@postgres:5432/book-service
AUTHOR_SERVICE_URL: author-service:50051
depends_on:
- postgres
- author-service
ports:
- "50052:50052"
volumes:
postgres_data:
Both services require Dockerfiles to define their environment, install dependencies, and run the applications.
FROM node:18-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 50051
CMD ["npm", "run", "start:prod"]
- Clone the repository and navigate to the project directory.
- Ensure Docker is installed and running on your system.
- Build and run the services using Docker Compose:
docker-compose up --build
The Author Service will be exposed at port 50051, and the Book Service will be exposed at port 50052. The PostgreSQL database will be accessible at port 5432.
- Install kubectl and configure it to connect to your Kubernetes cluster.
- Apply the Kubernetes deployment and service files:
kubectl apply -f author-service-deployment.yaml
kubectl apply -f book-service-deployment.yaml
kubectl apply -f postgres-deployment.yaml
kubectl apply -f database-secret.yaml
kubectl get pods
- createAuthor: Creates a new author.
message CreateAuthorRequest {
string name = 1;
string email = 2;
}
message Author {
string id = 1;
string name = 2;
string email = 3;
}
- getAuthor: Retrieves an author by id.
message GetAuthorRequest {
string id = 1;
}
message Author {
string id = 1;
string name = 2;
string email = 3;
}
- createBook: Creates a new book.
message CreateBookRequest {
string title = 1;
string authorId = 2;
int32 publishedYear = 3;
}
message Book {
string id = 1;
string title = 2;
string authorId = 3;
int32 publishedYear = 4;
}
- getBooksByAuthor: Retrieves all books by a specific author.
message GetBooksByAuthorRequest {
string authorId = 1;
}
message BookList {
repeated Book books = 1;
}