DDD CQRS Concurrency issue - api

We have set up an architecture based on DDD and CQRS. Additionally we have a restful API with an OAUTH implementation for our clients to connect to.
Our clients connect to our API and perform operations on behalf of their clients. Their clients are represented by profiles on our side.
We don't have a good solution for the following problem. Clients are able to create a profile by calling a method on our API. The problem is that we need to guarantee the uniqueness of the profiles. So what we currently do is check for an existing profile in the read model, create a command if it doesn't exist and return the profile ID back to the client so they can perform other API calls.
When a client performs multiple calls in rapid succession, a profile is created twice instead of once due to an out of date read model. We don't want that, but how do we resolve this issue?
We have thought about creating a saga to prevent more than one profile being created in the domain, but that is still problematic because we need to return the same profile ID to the client if their request is the same.
Any thoughts?

Commands are not supposed to return results.
What you can do is create a command that includes the ID of the new profile, if it is a GUID. If you are using a seeded identity column of some sort, of course this won't work.
But say that your ID is a GUID. Then you can pass a GUID in the command to the back end. The back end will create the new profile only if the GUID doesn't already exist -- and you have guaranteed unicity.

From what I understand from the CQRS pattern, the command layer should not make use of the read model to take any decision. The command layer do its processing based on the domain it self. Not based ont he read model. Validation is always made ont the domain data.
You profil creation command handler should check for the pre existence of the profil in the domain and not in the read model.

That's correct. Command should not rely on ReadModel, because of Eventually Consistent principle of ReadModel.
Just use your Domain in commands to make decision based on it.
Usually CQRS + EventSourcing repositories have very few methods, but on of them is GetById(Guid id). You can use it to check if such entity is already present in domain.

Related

Multi-tenancy in Golang

I'm currently writing a service in Go where I need to deal with multiple tenants. I have settled on using the one database, shared-tables approach using a 'tenant_id' decriminator for tenant separation.
The service is structured like this:
gRPC server -> gRPC Handlers -
\_ Managers (SQL)
/
HTTP/JSON server -> Handlers -
Two servers, one gRPC (administration) and one HTTP/JSON (public API), each running in their own go-routine and with their own respective handlers that can make use of the functionality of the different managers. The managers (lets call one 'inventory-manager'), all lives in different root-level packages. These are as far as I understand it my domain entities.
In this regard I have some questions:
I cannot find any ORM for Go that supports multiple tenants out there. Is writing my own on top of perhaps the sqlx package a valid option?
Other services in the future will require multi-tenant support too, so I guess I would have to create some library/package anyway.
Today, I resolve the tenants by using a ResolveTenantBySubdomain middleware for the public API server. I then place the resolved tenant id in a context value that is sent with the call to the manager. Inside the different methods in the manager, I get the tenant id from the context value. This is then used with every SQL query/exec calls or returns a error if missing or invalid tenant id. Should I even use context for this purpose?
Resolving the tenant on the gRPC server, I believe I have to use the UnaryInterceptor function for middleware handling. Since the gRPC
API interface will only be accessed by other backend services, i guess resolving by subdomain is unneccessary here. But how should I embed the tenant id? In the header?
Really hope I'm asking the right questions.
Regards, Karl.
I cannot find any ORM for Go that supports multiple tenants out there. Is writing my own on top of perhaps the sqlx package a valid option?
ORMs in Go are a controversial topic! Some Go users love them, others hate them and prefer to write SQL manually. This is a matter of personal preference. Asking for specific library recommendations is off-topic here, and in any event, I don't know of any multi-tenant ORM libraries – but there's nothing to prevent you using a wrapper of sqlx (I work daily on a system which does exactly this).
Other services in the future will require multi-tenant support too, so I guess I would have to create some library/package anyway.
It would make sense to abstract this behavior from those internal services in a way which suits your programming and interface schemas, but there's no further details here to answer more concretely.
Today, I resolve the tenants by using a ResolveTenantBySubdomain middleware for the public API server. I then place the resolved tenant id in a context value that is sent with the call to the manager. Inside the different methods in the manager, I get the tenant id from the context value. This is then used with every SQL query/exec calls or returns a error if missing or invalid tenant id. Should I even use context for this purpose?
context.Context is mostly about cancellation, not request propagation. While your use is acceptable according to the documentation for the WithValue function, it's widely considered a bad code smell to use the context package as currently implemented to pass values. Rather than use implicit behavior, which lacks type safety and many other properties, why not be explicit in the function signature of your downstream data layers by passing the tenant ID to the relevant function calls?
Resolving the tenant on the gRPC server, I believe I have to use the UnaryInterceptor function for middleware handling. Since the gRPC API interface will only be accessed by other backend services, i guess resolving by subdomain is unneccessary here. But how should I embed the tenant id? In the header? [sic]
The gRPC library is not opinionated about your design choice. You can use a header value (to pass the tenant ID as an "ambient" parameter to the request) or explicitly add a tenant ID parameter to each remote method invocation which requires it.
Note that passing a tenant ID between your services in this way creates external trust between them – if service A makes a request of service B and annotates it with a tenant ID, you assume service A has performed the necessary access control checks to verify a user of that tenant is indeed making the request. There is nothing in this simple model to prevent a rogue service C asking service B for information about some arbitrary tenant ID. An alternative implementation would implement a more complex trust-nobody policy whereby each service is provided with sufficient access control information to make its own policy decision as to whether a particular request scoped to a particular tenant should be fulfilled.

Using a Web API to perform 2 DB operations

I am doing my first tries with Web API and I have the following situation.
I need to perform 2 operations in a DB which must run inside a transaction:
1) Insert a record in one table (POST).
2) Update a record in another table (PUT).
Is it possible to do both in one call to a Web API?
If so, what verb should I specify: POST, PUT or another one?
With respect,
Jorge Maldonado
First off, your Web API should not be calling your DB directly at all. The Web API should be calling a service layer that then either calls your DB or calls repos.
The service layer can make as many calls to the DB as it needs to accomplish whatever the business rules are.
HTTP Verbs are not usually a hard rule for an action but in general, POST is for creating and PUT is for updating. In this case, if you are creating one record and also updating another record, I would default to POST.

CreateOrUpdate responsibility in an API

This is a generic design question, but where should the responsibility fall in this situation? Should it be the caller's responsibility to check if a record already exists and then call Update? Or should it be the responsibility of the API to make that decision?
In the first scenario, the problem is that the caller is burdened with the business logic, but in the second scenario, the logic pollutes the API and creates hybrid behavior, violating the separation of concerns principle.
Implementing a CreateOrUpdate endpoint will be breaking some REST principles, but may be convenient for the application developer. You are thinking in terms for a remote function call rather than in terms of resource-oriented API.
Consider this: the API URL identifies the resource.
If the URL points to a collection (i.e. /customers/) then the Create action (typically mapped to the POST method) certainly makes sense. The Update function might makes sense, if you want allow update to multiple resources at one. The POST should return code 201 and an identifier to a newly created resource (i.e. /customers/1); or if the create failed due to resource already existing it should return code 409; 400 if some other constraints like data validation are not met.
If the URL points to an existing resource (i.e. /customers/id/1) then Create action does not make sense and should result in code 400. The update is typically mapped to the PUT method (or sometiemes PATCH, if partial resource update) and generally would return 200 if the update was successful or 4xx series if not.
If you choose to create a /CreateOrUpdate endpoint, which takes POST requests you will have to design your own protocol around it because its behavior and return values will be different depending on circumstance.
#Evert the PUT can be used for create but only when you require client to formulate the endpoint URI with the identifier i.e.
PUT /users/myusername
Problems with that are:
the client must discover an available one,
if a natural identifier is used, there may also exist a natural reason for changing it, which depending on the implementation may be problematic
The main point I am making is to avoid creating REST API endpoints, which represent an action (function). Instead use HTTP methods to effect respective actions on persisted resources.

Good practice to achieve this eventual consistency

In my application, when a user is created, an Event called UserCreatedEvent is thrown.
This user must have all his description data retrieved from Facebook (with his authorization of course) and should be treated by some custom process.
I chose to apply eventual consistency (using Akka and his eventStream feature to handle events) between the fact of saving the user aggregate and the fact to retrieve all his description data and apply them, since it involves some call network to Facebook.
The point is I also allowed any newly created user to override some of the description (job, age etc.) through the REST api PUT /api/users/:id.
1) Should the process of handling UserCreatedEvent (basically an Akka actor) call this api (causing an indirection) to assign default user description (from Facebook) or should it retrieve and update user itself?
2) Should the process of handling UserCreatedEvent and the api aiming to manage User (CRUD) be part of the same bounded context? (in that case, no recommendation to involve the indirection).
I'm not sure I would call this eventual consistency, since consistency (making sure that an entity respects invariants) is not at stake. This is more like out-of-band asynchronous data completion.
What hoops this side process has to go through again basically depends on your context :
REST API if there's important stuff there you want to reapply (logging, security, whatever)
Application Service / Command handler layer if you want that data completion to be treated as a full blown modification with proper validation (e.g. did Facebook return data that would be unsupported in your application ?)
In the domain layer, you could model it either as just any other modification of the User, or as a specific, maybe more intention-revealing operation : User.completeDescriptionData(...)
I wouldn't necessarily place this in a different Bounded Context since it doesn't introduce a new definition of User. It's important that the part that knows the nitty gritty details of talking to Facebook is in a separate non domain layer though.

Entity Framework 4.1: how to work with per call life time data context?

According to this post, I am using a data context per call, so in each method of my WCF service, I use a using block to create a new data context.
But I have some doubts in the form to work in this way.
For example, I use a method getAllCLients() from my repository to get all the clients of the data base, then the service send to the client that call the method a list with all the clients. Then the user modify the information of some of them, three for example. The modify client perhaps I can add to a list that have the modified clients.
When I want to update this three clients, I can call a method updateClients() which receive a list of modified clients. How I am use a new data context per each method, in updateCients() get a new dataContext, without entities, so I think that I have to follow this steps:
1.- create a new data context which has the clients that I want to update. SO I need to specified the conditions for that. This is an extra operation (I get the clients before with the getAllClients() method), so I need to get again the clients.
2.- go throw the clients collection of the DBSet (I use EF 4.1) and change the information. This makes me to go throw the list that I receive from the client application too. So I must to go throw two lists. This needs resources.
3.- save the changes. This is needed anyway, so it has no required more work.
There is any way to make the step 2 easily? exist some method in dataContext to pass the values from my modified client to the client in the data context? I use POCO entities, perhaps it exists an easy way to do that.
Other question is about concurrency. If I control the concurrency with pesimistic concurrency that allow EF (with a timestamp field for example), is it better to call the updateClient() one for each client or better to pass a list with all the clients? I mean that if I use a list as parameter, if there is a concurrency issue with one client,the second for example, the first client will be update correctly, but the second not and the third neither. How can I notify to the user that there is problems with some clients?
To resume, I would like to know the best way to make updates when I have a short life datacontext.
Thanks.
Daimroc.
The service is disconnected scenario so when your client passes backs modified records you just need to process them as modified. You don't need to load all records from database for that.
public void SaveClients(List<Client> modifiedClients)
{
using (var context = new Context())
{
modifiedClients.ForEach(c =>
{
context.Entry(c).State = EntityState.Modified;
});
context.SaveChanges();
}
}
If you are using per call service and every service operation needs context you can move your context instancing to service constructor because service instance will live only to server single service call = you don't need using for every call. If you do that don't forget to implement IDisposable on your service to dispose context.
Other question is about concurrency. If I control the concurrency with
pesimistic concurrency that allow EF (with a timestamp field for
example), is it better to call the updateClient() one for each client
or better to pass a list with all the clients?
EF doesn't support pesimistic concurrency out of the box. Using timestamp is optimistic concurrency because it allows others to use the record. Pesimistic concurrency is application logic where other client is not able to select locked record for update.
The concurrency is resolved per record but the problem in this case is transaction. Each call to SaveChanges results in transaction used to process all changes in the database. So if any of your modified records is not up to date you will get concurrency exception and whole transaction is rolled back = no record is updated.
You can still overcome the issue by passing list of modified records to the service (reducing roundtrips between client and service is a best practice) but you can process each record separately by calling SaveChanges for every single record. Anyway this should be very carefully considered because each call to SaveChanges is like separate unit of work - is it really what you want?
Btw. the best practice is to make your service statless. You should avoid maintaining data between service calls and this example really doesn't need it.