Event Sourcing Order-Payment with NATS
===============
| event-store |
===============
/ \
grpc grpc
/ \
============= --> ========= ---> ===========
| front-end | GET, POST | order | nats | payment |
============= <-- ========= <--- ===========
Application Flow
- Order service acts as the main api gateway,
- Front-end applications send POST request to
/
to create order. - Order service records the request in its own
db
and callsevent-store
'screateEvent
grpc method. - Event-store saves the create event request in the
events
table and then publishesorder_created
onto thenats-streaming
network. - Payment service is subscribed to
order_created
event and processes the payment, and create events via call toevent-store
'screateEvent
grpc method. - Event-store publishes
payment_confirmed
if order description starts withtest
,payment_declined
if order description starts withxxx
, and a random pick betweenpayment_confirmed
&payment_declined
if not matched. - Order service is subscribed to
payment_confirmed
&payment_declined
event. Upon receiving either one of the event, it updates the order status toconfirmed
ifpayment_confirmed
,cancelled
ifpayment_declined
and create events usingevent-store
'screateEvent
grpc method. - Event-store publishes
order_confirmed
if payment was confirmed, andorder_cancelled
if payment was declined. - Order service is subscribed to
order_confirmed
and update the corresponding order status todelivered
upon receiving such event. - Event-store publishes
order_delivered
event.
Start docker services
docker-compose up -d
Start applications From project root, open 4 terminals
Terminal 1:
cd order
npm run dev
Terminal 2:
cd event-store
npm run dev
Terminal 3:
cd payment
npm run dev
Sample create order request
/POST localhost:3000, with the following body:
{
"amount": 207.00,
"description": "test top up e wallet"
}
Sample create order response
{
"id": "5e686586-5314-4f7d-bd0a-050cdca2d741"
}
Sample get order status request
/GET localhost:3000?id=5e686586-5314-4f7d-bd0a-050cdca2d741
Sample get order status response
{
"id": "5e686586-5314-4f7d-bd0a-050cdca2d741",
"amount": "207.00",
"user_id": "4391424b-6cc6-4f1d-a011-2f82ff293126",
"payee_id": "8c638d8e-f788-4111-9b05-7b49617015af",
"description": "test top up e wallet",
"status": "delivered",
"created_at": "2020-06-07T04:43:12.134Z",
"updated_at": "2020-06-07T04:43:12.234Z"
}
To run the integration test, ensure all the docker services have started and in proper order.
Then from project root, open 4 terminals (1-3 to start the services in development, and 4 to run the integeration test):
Terminal 1:
cd order
npm run dev
Terminal 2:
cd event-store
npm run dev
Terminal 3:
cd payment
npm run dev
Terminal 4
cd order
npm run test:integration
This assumes that you have helm installed.
From the project root:
helm install <release-name> helm-charts
To interact with the order api, the ip of the order service can be obtained via:
kubectl get svc/order
Sample output
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
order ClusterIP 10.43.219.72 <none> 3000/TCP 16s
Now can proceed to POST / GET to 10.43.219.72:3000 to create / get order.
To stop the stack:
helm uninstall <release-name>