Context
I'm giving a try at my first backend API which aim to follow some Domain Driven Architecture concepts that I've learned from an implementation in Go in a Udemy course.
The problem is that I don't clearly see the role of the Service.
In the course I've followed, there's a users-api
microservice and an oauth-api
.
The use case is fairly simple. It's an implementation of the OAuth password flow. In a few lines:
- The
oauth-api
microservice received a REST request containing a key and a secret - The
oauth-api
microservice sends a request to theusers-api
to know if the user exists - If so, The
oauth-api
microservice creates a token, persists it in a Cassandra DB and send it back in a JSON payload.
Here is the interesting part: the code architecture of the oauth-api
microservice.
The rectangles are simple packages and have their own responsibilities...
I started to list the responsibilities of each part to try to be able to reuse this pattern (or not if not relevant)
Application
- Creates & Launch a
Gin http server
- Bind the routes to the
Http functions
Http
- unmarshall the request body if there's one
- get the query parameters if there's one
- creates the
AccessTokenRequest
object - return an error if something went wrong with the previous steps
- marshall the response received from the
Service
- sends the final http response
Service
- validates the
AccessTokenRequest
object received fromHttp
by calling itsValidate
method - check if the user exists by performing a call to the
user-api
microservice by using aRestRepo
- creates an
AccessToken
object and persist it through the use of aDBRepo
Repositories
DBRepo
:- exposes a
CreateAccessToken
method to create an access token in Cassandra
- exposes a
UsersRepo
:- exposes a
LoginUser
method to call theusers-api
- exposes a
Client
- provides a
Cassandra client
to theOAuth-api
microservice.
Domain
- defines an
accessTokenRequest
object having a validation method which checks the grant type. - defines the
accessToken
object containing a validation method to check empty Field values.
Questions
The
AccessTokenRequest
object is part of the domain here. After reading a few articles about DDD, could we say that these kind of "Request Objects" (as well as some Response objects I guess) can be considered as Entities or Value Objects?The
DBRepo
contains just simple CRUD operations and it's great because it fits perfectly the expected output. But sometimes, we may need more complex DB queries.
Let say we have 3 tables: customers
, orders
and orderItems
like below ...
... and we need to be able to POST an order... Is is ok to perform a single SQL transaction from a single OrderRepository
?
- In my app, my services uses repos which creates the objects and I don't see validation for them to perform ... and if they don't need to call another microservice ... I find them a bit useless. Maybe I missed something about the roles of Services. And I have to day that I don't see examples in which I would need to use several repositories in a single service if you have some (aside from an authentication service).
So for now, my backend just looks like a simple Gateway calling a REST API composed of independent services: Authentication (handled by the Gateway), Customers, Orders and Payments (this last one still to be implemented)
if we take the orders + orderItems example
, let's say we have 10 items per order on average, and that it's read intensive. I don't see the benefit of dealing with 2 repositories: one for the order table and another for the items, or 2 services. Especially, from what I've read, this would imply the need to implement Sagas
when receiving a write order request (or Two Phase Commit
)... What do you think?
Maybe, from a Domain perspective, there's not enough complexity in my little project to make use of microservices for now.