Using a Web API to perform 2 DB operations - asp.net-web-api2

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.

Related

RESTful / Crud based approach to controlling an entity behavior that is typically implicit

I am modifying a CakePHP application to have an API available on it. My intention is to try to keep keep the endpoints as close to being RESTful / Crud oriented as possible. Although I have a use case that that I am unsure of.
I have the following requests for adding and editing tasks:
PUT /tasks
PATCH /tasks/:id
One of the behaviors of task entity in the system I am working on is that they send emails to the effected users associated with the task, when a save or edit is performed. This allows the various parties surrounding the task to be updated on the status of the particular task.
However the the one issue is that in some uncommon cases the end user will need to be able to toggle if they want an email to be sent on the front end.
What is the proper RESTful / Crud oriented approach to flag the task endpoints to not fire the email in the API request?
There is no record of the email in the application's database and it is nice to have to functionality tied into the task life cycle hooks and called implicitly. So I am not crazy about doing something like creating an /emailTask set of endpoints. It seems like an optional flag in the task request would be cleaner, but might not be maintainable if we begin to have similar needs for other behaviors associated with tasks.
Thanks in advance for the help!
PUT /tasks
If you're intending to use this for adding tasks, use POST instead. PUT /tasks implies that you are overwriting all tasks.
As for side-effects, this to me feels like a decent use-case for a custom HTTP header. Perhaps something like Suppress-Notifications: ?1 ?
Why ?1 as a value? This is going to be the future default for new HTTP headers that specify a boolean:
https://datatracker.ietf.org/doc/html/draft-ietf-httpbis-header-structure-15#section-4.1.9

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.

Calling ASP.NET Web Api to do some actions

I am creating a Web Api integrates with SignalR.
I want to create a Web Api method that will receive a string/object as parameter (from an winform exe) and broadcast it to all the SignalR clients.
I know that Web Api uses HTTP requests like PUT DELETE POST GET. All of these requests are database related, i.e. PUT for Update, DELETE for Delete, POST for Insert, GET for Select.
In this case, which HTTP request should I use?
public void BroadcastToClients() {}
Or should I consider WCF instead of Web Api?
People tend to get all up-tight about "pure" REST vs just getting something to work. For every cited reference that argues for one scheme, you can find another that is the opposite.
My very personal opinion is that POST is when something new is to be created, and PUT when an entity is to be updated.
I think the important thing is to just be consistent.

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.

DDD CQRS Concurrency issue

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.