Git Product home page Git Product logo

bookstore's Introduction

bookstore

Architecture Overview

Microservices
│
├── UserService/
│
├── TokenService/
│
├── InventoryService/
│
└── OrderService/
  • UserService: Manages the user registration and login. It's responsible for user authentication and authorization.

  • TokenService: Manages the user's balance and the user's purchase token. It's responsible for the user's balance and the user's purchase token.

  • InventoryService: Manages the books and the inventory. It's responsible for the books and the inventory.

  • OrderService: Manages the orders and the order processing. It's responsible for the orders and the order processing.

Communication

diagram.jpg

Technologies

  • .NET 8.0: The services are built with .NET 8.0.

  • Docker: The services are containerized with Docker.

  • Docker Compose: The services are orchestrated with Docker Compose.

  • PostgreSQL: The database is PostgreSQL.

  • Redis: The cache is Redis.

  • Kafka: The message broker is Kafka.

  • Swagger: The services are documented with Swagger.

  • xUnit: The tests are written with xUnit.

Requirements

Running the tests

1. Clone the repository

git clone https://github.com/mojbaba/bookstore.git

2. Change into the directory

cd bookstore

There are integration tests which test the services in isolation but with the real database, redis and kafka. They test each service use case and the flow of the services.

  • Integration tests use TestContainers to run the real database, redis and kafka in the docker containers. So you need to have docker and docker-compose installed.

there should be lots of unit tests for each service, but I didn't have enough time to implement them.

dotnet test

Running the application

1. Clone the repository

git clone https://github.com/mojbaba/bookstore.git

2. Change into the directory

cd bookstore

3. Run the infrastructure

docker compose --file docker-compose.infra.yml up -d

if you get network error, you can create a network with the following command:

docker network create bookstore

4. Run the migrations

docker compose --file docker-compose.migrations.yml up -d

5. Run the application

docker compose --file docker-compose.apis.yml up -d

6. Open your browser

it was better to have a single entry point for all services, but I didn't have enough time to implement it. (Nginx, Ocelot, etc.)

7. Register a user

on Swagger UI (UserService -> register)

{
  "email": "[email protected]",
  "password": "string"
}

8. Login and get a token

on Swagger UI (UserService -> login)

{
  "email": "[email protected]",
  "password": "string"
}

and get a token

{
  "email": "[email protected]",
  "token": "{JWT_TOKEN}"
}

9. Create a book

on Swagger UI (InventoryService -> create)

{
  "title": "Book store micoservice architecure",
  "author": "Mojbaba",
  "price": 20,
  "amount": 1
}

get the book id

{
  "bookId": "{GUID}"
}

10. Authorize to the Token Service

on Swagger UI use Authorize button and add the token {JWT_TOKEN} got from step 8.

11. Add Book Purchase Token

on Swagger UI (TokenService -> add)

{
  "amount": 1500
}

12. Authorize to the Order Service

on Swagger UI use Authorize button and add the token {JWT_TOKEN} got from step 8.

13. Create an order

on Swagger UI (OrderService -> create)

{
  "bookIds": [
    "{the book id got from step 9}"
  ]
}

14. Get the order

on Swagger UI (OrderService -> Admin Orders)

you can track the order statuses.

"isPaymentProcessed": true and "isInventoryProcessed": true means the order is processed successfully.

"isPaymentProcessed": true means the TokenService got the OrderCreatedKafkaEvent and deducted the amount from the user's account

[
  {
    "id": "string",
    "userId": "string",
    "status": 0,
    "createdAt": "2024-02-24T03:44:56.287Z",
    "isPaymentProcessed": true,
    "isInventoryProcessed": true,
    "failReason": "string"
  }
]

15. Track the user balance

on Swagger UI (TokenService -> balance) (must authorize with the token got from step 8)

{
  "userId": "{GUID}",
  "balance": {NEW_BALANCE}
}

the user's balance is deducted by 1500 after the order is processed.

the inventory service is not completely implemented, so the inventory is not deducted after the order is processed. it just accepts the order anyway and published success packed books event

Notes

  • In real world, the services should be deployed in the kubernetes cluster.

  • Each service repository should be separated and have its own CI/CD pipeline.

  • The project with the name BookStore.* are the libraries and the shared code between the services. they should be separated and have their own CI/CD pipeline. and should be published to the private nuget repository. (I dont like to use some Common or Shared libraries, because they are not maintainable and they are not designed to be used in the other projects. they are just a bunch of code that are not related to each other.)

  • The authorization are implemented with JWT. so when user log out, the token is blacklisted and the user can't use it anymore. the other services get notified by the the Kafka event.

  • The blacklisted tokens are stored in the Redis cache with some expiration time.

  • The services are not completely implemented, so there are some missing parts and bugs.

  • Services are totally stateless and can be scaled horizontally.

  • API Gateway, Circuit Breaker, Rate Limiting, etc. are not implemented.

  • Notifications, Logging, Monitoring, etc. are not implemented.

  • It can be implemented with gRPC instead of REST inter-comunications.

  • The services are not Completly DDD, CQRS, Event Sourcing, but they are designed to be implemented with these patterns.

  • The event log consumers are the default kafka consumers, which means they are garantee at least once delivery. but each service stores the events in the database and checks the event id to prevent duplicate processing.

bookstore's People

Contributors

mojbaba avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.