Carlos García de Marina Vilar - garciademarina@gmail.com
-
Please write a new Microservice called “Order Service” which will: a. Support the Standard Order Flow for an Ecommerce Order
b. Consider an Order Object to have the following details
i. Order Id, ii. Total amount iii. Order Lines, where each line is a collection of 1. Item SKU 2. Price 3. Quantity iv. Order Shipping Address v. Order Billing Addresss
c. Consider the following to be standard order statuses
i. Pending Confirmation ii. Confirmed iii. Sent to Warehouse iv. Shipped v. In Transit vi. Delivered
d. The Microservice will provide relevant API calls for Order Creation, Status Updates e. The Microservice should generate relevant Events for each order status updates f. The service should have its own NoSQL persistence Layer
cd $GOPATH/src/github.com/garciademarina/deporvillage
docker-compose build
docker-compose up -d
Requires Go 1.12 or later. Requires mongodb, check cmd/config.json in order to update mongodb url, port and database.
go get -u github.com/garciademarina/deporvillage
Add new Order
curl -v -X POST "http://localhost:8080/order" -H "accept: application/json;" -d '{"id":2,"amount":10,"status":"cli","order_lines":[{"sku":"TROP-UA-PLAS-09","price":10,"quantity":1},{"sku":"TROP-NP-PLAS-65","price":10,"quantity":2},{"sku":"TROP-LT-PLAS-89","price":5,"quantity":10}],"shipping_address":{"first_name":"Jhon","last_name":"Snow","email":"j.snow@example.com","company":"Acme","phone":"555000111","line1":"711-2880 Nulla St.","line2":"","line3":"","city":"Mankato","country":"Mississippi","zip":"96522"},"billing_address":{"first_name":"Jhon","last_name":"Snow","email":"j.snow@example.com","company":"Acme","phone":"555000111","line1":"711-2880 Nulla St.","line2":"","line3":"","city":"Mankato","country":"Mississippi","zip":"96522"}}'
Update status Order
curl -v -X PUT "http://localhost:8080/order" -H "accept: application/json;" -d '{"id":2,"status":"confirmed"}'
Get Order by ID
curl -v -X GET "http://localhost:8080/order/2" -H "accept: application/json;"
- Successfull request will return http status code 200 along with a json with additional information (or not).
- Failed request will return http status code 40X along with a json with additional information of the error.
Type (string) Posible values api_error
Code (string) Optional code
Message (string) A string representation for the error
Http server, set up all API routes using injected services from cmd/api/main.go
pkg/server
/pkg/adding /pkg/updating /pkg/listing
Repositories satisfy the Repository interface, this way we can swap mongodb by another noSQL database or SQL o in-memory implementation.
/pkg/storage/mongodb
http handler used by server.go, handlers will use injected services from pkg/server.go
-
ShippingAddress and BillingAddress has their own struct, this way in the future we can get reports like: All order with "shipped" status where shipping city is Madrid.
-
I asume "PUT /order" endpoint only updated the order status. If all order fields needs to be updated, it should be easy to implement by just adding the missing order fields.
-
Status must be one of the following: pending_confirmation, confirmed, sent_to_warehouse, shipped, in_transit, delivered
-
Events are sent to rabbitmq. List of event:
-
"order_added",
824635283344-order_added
example: "OrderID - order_added"
-
"order_status_updated",
824635283344-order_status_updated [confirmed]
example "OrderID - order_status_updated [STATUS]
* using docker you can check all rabbitmq messages from http://localhost:15672/ (guest/guest)
-
Get the current order given an order ID. {ID}
Arguments
- ID (required) A string ID of an order
Response Order object
{
"id":2,
"amount":10,
"status":"confirmed",
"order_lines":[
{
"sku":"TROP-UA-PLAS-09",
"price":10,
"quantity":1
},
{
"sku":"TROP-NP-PLAS-65",
"price":10,
"quantity":2
},
{
"sku":"TROP-LT-PLAS-89",
"price":5,
"quantity":10
}
],
"shipping_address":{
"first_name":"Jhon",
"last_name":"Snow",
"email":"j.snow@example.com",
"company":"Acme",
"phone":"555000111",
"line1":"711-2880 Nulla St.",
"line2":"",
"line3":"",
"city":"Mankato",
"country":"Mississippi",
"zip":"96522"
},
"billing_address":{
"first_name":"Jhon",
"last_name":"Snow",
"email":"j.snow@example.com",
"company":"Acme",
"phone":"555000111",
"line1":"711-2880 Nulla St.",
"line2":"",
"line3":"",
"city":"Mankato",
"country":"Mississippi",
"zip":"96522"
}
}
Create a new order
Arguments (json body) Order object
{
"id":2,
"amount":10,
"status":"confirmed",
"order_lines":[
{
"sku":"TROP-UA-PLAS-09",
"price":10,
"quantity":1
},
{
"sku":"TROP-NP-PLAS-65",
"price":10,
"quantity":2
},
{
"sku":"TROP-LT-PLAS-89",
"price":5,
"quantity":10
}
],
"shipping_address":{
"first_name":"Jhon",
"last_name":"Snow",
"email":"j.snow@example.com",
"company":"Acme",
"phone":"555000111",
"line1":"711-2880 Nulla St.",
"line2":"",
"line3":"",
"city":"Mankato",
"country":"Mississippi",
"zip":"96522"
},
"billing_address":{
"first_name":"Jhon",
"last_name":"Snow",
"email":"j.snow@example.com",
"company":"Acme",
"phone":"555000111",
"line1":"711-2880 Nulla St.",
"line2":"",
"line3":"",
"city":"Mankato",
"country":"Mississippi",
"zip":"96522"
}
}
Response
{
"success":"ok"
}
Update order status.
{
"id":2,
"status":"confirmed"
}
Response
{
"success":"ok"
}
-
I had some issues because the api container started before rabbitmq, so I made a simple bash script to delay 30 seconds the start of the api.
-
Partially tested, here some test for adding package
https://github.com/garciademarina/deporvillage/tree/master/pkg/adding
- Once the order service is almost ready, how will you deploy the service to a cloud hosting? You can try to summarize your solution using
- As I already have a dockerimage that contains only one executable file, it should be easy to deploy the container to kubernetes, I will need to upload the docker image to a repository and then just create the kubernetes job to deploy the uploaded image inside the kubernetes cluster. (I have limit knowlage of kubernetes)
a) CI/CD? How? Which tools?
Jenkings, (it's the only one I worked with). Using github webhooks, on every commit/merge to master branch should trigger the CI/CD pipeline. Once the webhook is received the docker image is updated, test are executed and if all test are successful then just update/updoad the docker image to the repository and deploy the new version to kubernetes.
b) Monitoring & Alerts? Any concrete tool?
Prometheus, it's a monitoring system that also have an alerting system.
c) Logging?
ELK (elasticsearch , logstash, kibana)
- logstash, parse logs generated by the api.
- elasticsearch, used to store logs.
- kibana, used to explore and visualize logs.
d) Deployment - Microplatform (AMI) vs Kubernetes?
With my limited experience with kubernetes, It shoud be easy to deploy de api to kubernetes. Mongodb instance can be deployed to kubernetes or an external service selfmanaged.