{"id":13601240,"url":"https://github.com/twzhangyang/RestAirline","last_synced_at":"2025-04-11T03:32:50.219Z","repository":{"id":41494841,"uuid":"133215266","full_name":"twzhangyang/RestAirline","owner":"twzhangyang","description":"DDD+CQRS+EventSourcing+Hypermedia API+ASP.NET Core 3.1+Masstransit+terraform+docker+k8s","archived":false,"fork":false,"pushed_at":"2023-03-03T23:26:35.000Z","size":649,"stargazers_count":349,"open_issues_count":1,"forks_count":73,"subscribers_count":17,"default_branch":"master","last_synced_at":"2024-11-07T04:39:49.789Z","etag":null,"topics":["aspnet-core","aspnetcore","aspnetcore2","cqrs","ddd","docker-compose","eventflow","eventsourcing","hypemedia","hypermedia-api","k8s-deployment","restful-api"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/twzhangyang.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null}},"created_at":"2018-05-13T07:31:09.000Z","updated_at":"2024-09-22T18:40:04.000Z","dependencies_parsed_at":"2024-01-15T13:36:04.778Z","dependency_job_id":null,"html_url":"https://github.com/twzhangyang/RestAirline","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twzhangyang%2FRestAirline","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twzhangyang%2FRestAirline/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twzhangyang%2FRestAirline/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/twzhangyang%2FRestAirline/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/twzhangyang","download_url":"https://codeload.github.com/twzhangyang/RestAirline/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248335600,"owners_count":21086627,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["aspnet-core","aspnetcore","aspnetcore2","cqrs","ddd","docker-compose","eventflow","eventsourcing","hypemedia","hypermedia-api","k8s-deployment","restful-api"],"created_at":"2024-08-01T18:00:59.129Z","updated_at":"2025-04-11T03:32:45.205Z","avatar_url":"https://github.com/twzhangyang.png","language":"C#","funding_links":[],"categories":["C# #","C\\#","Architectural Patterns"],"sub_categories":["Microservices"],"readme":"[![Build Status](https://dev.azure.com/restairline/restairline/_apis/build/status/twzhangyang.RestAirline?branchName=master)](https://dev.azure.com/restairline/restairline/_build/latest?definitionId=5\u0026branchName=master)\n\n# Overview\n\n* A classic DDD with CQRS-ES, Hypermedia API and Ubiquitous unit test project based on EventFlow. It's targeted to ASP.NET Core 3.1 and can be deployed to docker and k8s\n* Based on [EventFlow](https://github.com/eventflow/EventFlow)\n* Based on ASP.NET Core3.1\n* Implement read model by EntityFramework, MongoDB, Elasticsearch\n* Integrate RabbitMQ and used [MassTransit](https://github.com/MassTransit) as Message bus (in progress)\n* Event driven Microservices integration (in progress)\n* Infrastructure as code by Terraform, AWS eks was created for shipping this application\n* [Wiki](https://github.com/twzhangyang/RestAirline/wiki) is in progress\n\n# The idea of this project\n* **CQRS** helps modelling pure domain by separating command and query logic\n* **Event Sourcing** helps decoupling domain models and persistence\n* **Combining CQRS and Event Sourcing** make the domain model more reasonable and pure\n* At the same time, different Bounded contexts can evolve into different Microservices and different Microservices can interact through asynchronous **Message Bus** and **events**\n* In the end, we got a Microservices architecture based on DDD. A single Microservices ensures the purity of the domain model through CQRS and Event Sourcing. Different Microservices can interact through the message bus. Finally, all services can be deployed to cloud and k8s\n\n# The Domain and Bounded context\nThe example is regarding online booking/checkin for an airline company. An airline company named 'RestAirline' is offering online booking/checkin. \nThere are four possible Bounded context for above business: \n* `Booking` is a bounded context that focusing on online booking;\n* `Flight Availability` is a bounded context that focusing searching available flights and flight schedule;\n* `Checkin` is a bounded context that focusing on online checkin;\n* `Seat Availability` is a bounded context that maintaining seat for each flight;\n![domain](https://user-images.githubusercontent.com/22952792/59654892-bbb2f680-91ca-11e9-8465-a628a57e13b2.png)\n\n## The Microservices and communication\nGenerally each bounded context can be build as a standalone Microservice, For now I just created two Microservices: `Booking` and `FlightAvailability`.\nThere are some interactions between these two Microservices, the obvious action is when passenger selected flight in `Booking` Microservice,\nThe available amount of flights in `FlightAvailability` Microservice should subtract corresponding amount. The idea is when passenger selected a flight in `Booking`\nservice, A event named `JourneysSelectedEvent` will be published to message bus, Any Microservices who are interested in this event can subscribe this event \nand handle it. \n\n# How to Run\n## Clone this repo\n\n\u003e git clone https://github.com/twzhangyang/RestAirline.git\n\n## Running the container\nThen spin up a new container using `docker-compose`\n\n\u003e docker-compose up\n\nNote: add a `-d` to run the container in background\n\nAn API service and mssql will run in docker\n\n## Run in local\nThis project based on .NET Core 3.1, please install corresponding SDK for your operating system:\n\nAfter installing, please run below command to make sure current .NET Core version is 3.1.101\n`dotnet --version`\n\n## Run the API\n\n### 1. Try to input home api link in Postman:\n\n\u003e GET http://localhost:61200/booking/home/\n\n---\n\n### 2. Select Journeys\nJourney items should come from another micro-service named flight availability, for now let's build a \njourney in the api automatically for convenience. So you need not pass any journey id to this api.\n\n\u003e POST /booking/journeys\n\n![add journey](https://user-images.githubusercontent.com/22952792/61993523-7625fb00-b09f-11e9-98a4-5fdd52774996.png)\n---\n\n### 3. Add passenger\nWe can get request body schema from last Api response become the whole Api is designed by Hypermedia.\nThe api definition is totally described by last api response under `resourceCommands\\addPassengerCommand`:\n```\n\"addPassengerCommand\": \n{\n    \"bookingId\": \"booking-352cb1f3-0f68-4e04-a2f7-24036eb53ce7\",\n    \"name\": null,\n    \"passengerType\": 0,\n    \"age\": 0,\n    \"email\": null,\n    \"postUrl\": {\n        \"uri\": \"/booking/booking-352cb1f3-0f68-4e04-a2f7-24036eb53ce7/passenger\"\n    }\n}\n```\nObviously the endpoint is: \n\n\u003e http://localhost:61100/booking/booking-352cb1f3-0f68-4e04-a2f7-24036eb53ce7/passenger\n\nThe payload schema is:\n```\n{\n\t\"bookingId\": \"booking-352cb1f3-0f68-4e04-a2f7-24036eb53ce7\",\n    \"name\": null,\n    \"passengerType\": 0,\n    \"age\": 0,\n    \"email\": null,\n}\n```\n`bookingId` is filled already, please try to fill other parameters, eg:\n```\n{\n\t\"bookingId\": \"booking-352cb1f3-0f68-4e04-a2f7-24036eb53ce7\",\n    \"name\": \"test\",\n    \"passengerType\": 0,\n    \"age\": 22,\n    \"email\": \"test@test.com\",\n}\n```\nSend request:\n\n\u003e POST booking/{bookingId}/passenger\n\n![add booking](https://user-images.githubusercontent.com/22952792/61993532-b8e7d300-b09f-11e9-9567-75ba0ea0a8d9.png)\n---\n\n### 4. Get booking\nAccording to response of last api, you can either get the booking by `resourceLinks` or post data by `resourceCommand`.\n\n\u003e GET /booking/{bookingId}\n\n![get booking](https://user-images.githubusercontent.com/22952792/61993549-ffd5c880-b09f-11e9-9679-e708a7f087d3.png)\n---\n\n### 5. Update passenger Name\n\n## Business \nThe example is regarding online booking for an airline company. An airline company named 'RestAirline' is offering online booking. \n* After passenger submitted one of the available journey that means this passenger starting create an online booking.\n* passenger can submit multiple available journeys, every journey including a flight.\n* After passenger added journeys, he/she can add passengers.\n* Once passenger have been added in booking, passenger can update passenger name for each passenger.\n* passenger can submit available seats for each flight and each passenger, seat may just including seat number.\n* Once passenger submitted seats, passenger still can update seat.\n* After all of these steps, passenger have a chance to order insurance for all passenger some of them.\n* Last step is pay for all booking, if payment is successful then create a pnr(six digit) for this booking.\n* Online checkin is allowed for all the flights. Passenger can checkin at below time window:\n\n\u003e 2h \u003c= timeWindow \u003c= departure time - 30m \n\n* Passenger can do online checkin, after this step passenger start to his/her journey. \n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwzhangyang%2FRestAirline","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftwzhangyang%2FRestAirline","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftwzhangyang%2FRestAirline/lists"}