A Spring Boot microservices project for managing patients, authentication, billing account creation, and patient analytics events.
The project demonstrates a practical microservice architecture using REST APIs, Spring Cloud Gateway, JWT authentication, gRPC, Kafka, Protobuf, Spring Data JPA, and Maven.
Client
|
v
API Gateway :4004
|---------------------> Auth Service :4005
|
| JWT-protected route
v
Patient Service :4000
|---------------------> Billing Service gRPC :9002
|
| Kafka patient event
v
Analytics Service
| Service | Port | Responsibility |
|---|---|---|
| API Gateway | 4004 |
Single entry point, routes requests, validates JWT for protected patient APIs |
| Auth Service | 4005 |
User login, BCrypt password verification, JWT generation and validation |
| Patient Service | 4000 |
Patient CRUD, validation, persistence, billing integration, Kafka event publishing |
| Billing Service | 4001, gRPC 9002 |
Internal billing account creation API over gRPC |
| Analytics Service | default Spring port | Consumes patient events from Kafka |
- Java 21
- Spring Boot
- Spring Cloud Gateway
- Spring Security
- Spring Data JPA
- PostgreSQL / H2 support depending on service configuration
- gRPC
- Protocol Buffers
- Apache Kafka
- Maven
- RestAssured for integration tests
- Dockerfiles for each service
- Client calls
POST /auth/loginthrough the API Gateway. - Gateway forwards the request to Auth Service.
- Auth Service verifies the user password using BCrypt.
- Auth Service returns a signed JWT.
- Client sends the token as:
Authorization: Bearer <token>- Client calls
POST /api/patientswith a valid JWT. - API Gateway validates the JWT by calling Auth Service.
- Gateway forwards the request to Patient Service.
- Patient Service validates the request and checks duplicate email.
- Patient Service saves the patient.
- Patient Service calls Billing Service over gRPC.
- Patient Service publishes a patient-created event to Kafka.
- Analytics Service consumes the event asynchronously.
patient-management/
api-gateway/
auth-service/
patient-service/
billing-service/
analytics-service/
integration-tests/
INTERVIEW_PREP.md
pom.xml
Install these before running the project:
- Java 21
- Maven 3.9+
- Docker, optional but useful for databases/Kafka
- PostgreSQL, if running services with Postgres
- Kafka, if testing event publishing and analytics
- An API client such as Postman, Insomnia, curl, or IntelliJ HTTP Client
Clone the repository:
git clone <your-repository-url>
cd PatientManagement_Microservice/patient-managementBuild all Maven modules:
mvn clean packageIf you want to skip tests during the first build:
mvn clean package -DskipTestsSome services need runtime properties. You can pass them as environment variables or command-line properties.
The gateway needs the Auth Service URL:
--auth.service.url=http://localhost:4005The patient service needs to know where Billing Service is running:
--billing.service.address=localhost
--billing.service.grpc.port=9002If Kafka is running somewhere other than localhost:9092, configure:
--spring.kafka.bootstrap-servers=localhost:9092If using PostgreSQL, configure datasource properties:
--spring.datasource.url=jdbc:postgresql://localhost:5432/patient_db
--spring.datasource.username=postgres
--spring.datasource.password=postgres
--spring.jpa.hibernate.ddl-auto=update
--spring.sql.init.mode=alwaysAuth Service already contains a sample JWT secret in application.properties. For real projects, pass the secret from an environment variable or secret manager.
Example database configuration:
--spring.datasource.url=jdbc:h2:mem:authdb
--spring.datasource.driver-class-name=org.h2.Driver
--spring.datasource.username=sa
--spring.datasource.password=
--spring.jpa.hibernate.ddl-auto=update
--spring.sql.init.mode=alwaysOpen separate terminals and start the services in this order.
cd auth-service
mvn spring-boot:run -Dspring-boot.run.arguments="--spring.datasource.url=jdbc:h2:mem:authdb --spring.datasource.driver-class-name=org.h2.Driver --spring.datasource.username=sa --spring.datasource.password= --spring.jpa.hibernate.ddl-auto=update --spring.sql.init.mode=always"cd billing-service
mvn spring-boot:runBilling Service uses:
- HTTP:
4001 - gRPC:
9002
For H2-based local development, make sure H2 is available in the service dependencies or configure PostgreSQL.
PostgreSQL example:
cd patient-service
mvn spring-boot:run -Dspring-boot.run.arguments="--billing.service.address=localhost --billing.service.grpc.port=9002 --spring.datasource.url=jdbc:postgresql://localhost:5432/patient_db --spring.datasource.username=postgres --spring.datasource.password=postgres --spring.jpa.hibernate.ddl-auto=update --spring.sql.init.mode=always --spring.kafka.bootstrap-servers=localhost:9092"Start this after Kafka is running:
cd analytics-service
mvn spring-boot:run -Dspring-boot.run.arguments="--spring.kafka.bootstrap-servers=localhost:9092"cd api-gateway
mvn spring-boot:run -Dspring-boot.run.arguments="--auth.service.url=http://localhost:4005"The application entry point is now:
http://localhost:4004
Seed credentials from auth-service/src/main/resources/data.sql:
email: testuser@test.com
password: password123
Request:
curl -X POST http://localhost:4004/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "testuser@test.com",
"password": "password123"
}'Response:
{
"token": "eyJhbGciOiJIUzI1NiJ9..."
}curl http://localhost:4004/api/patients \
-H "Authorization: Bearer <token>"curl -X POST http://localhost:4004/api/patients \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Ravi Kumar",
"email": "ravi.kumar@example.com",
"address": "Bhubaneswar, Odisha",
"dateOfBirth": "1998-05-10",
"registeredDate": "2026-06-08"
}'curl -X PUT http://localhost:4004/api/patients/<patient-id> \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"name": "Ravi Kumar Updated",
"email": "ravi.updated@example.com",
"address": "Cuttack, Odisha",
"dateOfBirth": "1998-05-10",
"registeredDate": "2026-06-08"
}'curl -X DELETE http://localhost:4004/api/patients/<patient-id> \
-H "Authorization: Bearer <token>"The integration tests expect the services to be running through the API Gateway at:
http://localhost:4004
Run tests:
cd integration-tests
mvn testEach service contains its own Dockerfile. Example:
cd auth-service
docker build -t patient-auth-service .
docker run -p 4005:4005 patient-auth-serviceRepeat for other services as needed.
There is currently no docker-compose.yml in the repository. To run the full system with Docker, add a Compose file for:
- API Gateway
- Auth Service
- Patient Service
- Billing Service
- Analytics Service
- PostgreSQL
- Kafka
- Zookeeper or Kafka KRaft setup
api-gatewayrequiresauth.service.url.billing-serviceis configured with gRPC port9002, while its Dockerfile exposes9001; align these before Docker-based deployment.patient-serviceshould be run withbilling.service.grpc.port=9002.patient-servicecurrently publishes Kafka events to topicPATIENT_CREATED.analytics-servicecurrently listens to topicpatient; align the topic names before relying on analytics events.- In production, do not keep JWT secrets in
application.properties.