Request is received using a dedicated request struct CreateOrderRequest
this request struct has all the relevant annotations and validations for that request ONLY, it can use shared records, something like types.AddressRequest
but shared types MUST be setup for request validation also.
IMPORTANT do not use data from order service or API here as it will make it easy to break API contracts
the CreateOrderRequest
will be validated using go validator and there is example code on how to use that. It will automatically run any nested validations, for available validations check go validator docs
There should also be an appropriate CreateOrderResponse
Call a domain service with the relevant data that the domain expected, as domain services cannot have awareness of api structs, you need to convert into something the internal domain expected, this is one idea behind a unified standard internal data schema, so you always know what you want to convert into
Now I know in the case of fulfilment was want to call ex api to create the order, but as thats part of the domain responsibility, I think it make sense to first convert into a domain struct, then back out to the ex api data, that will also give is better ownershiup and clarity on the data we care about, and easier migration away from ex-core api.
So typically here if you have convertors, they can live in the api layber, but their job is to convert to internal data
CreateOrderRequest -> data.PickingOrder for example
Then something like domainService.CreateOrder(ctx, convertedOrder)
As fulfilment public api is meant to just be a convenient public facing wrapper around our fulfilment domain, I don't think any data structs should exist here, like data.PickingOrder, that should live in fulfilment/domain/data (or similar) if you already have data.PickingOrder, then this should be called something else.
You can have the service to receive the CreateOrder request in the fulfilment_public/domain or fulfilment/domain so long as the data structs are not in the public one
Typically in this layer we would persist the order, but in the case of fulfilment right now this would convert from unified data and make a request to ex_core_api
Essentially we are saying that both sides of the interation, the public API and ExCoreAPI should be able to convert to the common data struct, the conversion into the common data should ideally not be in the domain but between the domain and the external call, this we we can ensure we don't get any circular dependencies, and data is flowing the right with, and we don't inadvertantly break API contracts by changing underlying data types