Using transactions in ASP.NET Web API - c#

I have two different calls to controller in Web API. Let's say that the route for a first one is http://localhost/1 and for second http://localhost/2
My goal is to do something like transactions. In a first call I want to send data to server. So this is where my first question comes: How can I save data for a short time on server, and not saving it into database? What's the best practice for this?
In second call I'm sending verification code. If code is ok, than I will do something with data that client send in previous call.
This sounds like a transaction to me. Like commit if code is ok or rollback transaction if code verification faild, but I'm not sure is it possible to use transactions in this kind of scenarios, when you have two different POST methods.
Can someone help me with thinking about this little bit more?

Dont save anything temporarily in server. That's a bad practice.
WebApi is stateless. So, its better to save every details in server.
In the first POST call, return a unique transaction reference number (Use SQL server to save this information)
E.g. POST to http://localhost/requestVerificationNumber/ which returns a GUID
In the second POST call, cross check the verification code by matching it with the unique transaction number stored before. It is the responsibility of the second POST call to send that reference number.
E.g. POST to http://localhost/verifyCode/ along with the GUID sent before.
The advantage of this method is that all the transactions are stored in Sql Server and later be manipulated.

Related

Synchronizing data between client and API (Database) .NET 6

I am currently working on a task where I need to synchronize the data, example:
Client makes a request to get data to the API (API has access to the database), client received the data and saves it to the list. That list is used for some time etc..... Then in the meanwhile another client accesses the same API and database and makes some changes... to the same table... After a while the first client want's to update his current data, since the table is quite big let's say 10 thousand records, grabbing the entire table again is inefficient. I would like to grab only the records that have been modified,deleted, or newly created. And then update the current list the client 1 has. if the client has no records, he classifies all of them as newly created (at start up) and just grabs them all. I would like to do as much checking on the client's side.
How would I go about this ? I do have fields such as Modified, LastSync, IsDeleted. So I can find the records I need but main issue is how to do it efficiently with minimal repetition.
At the moment I tried to get all the rows at first, then after I want to update (Synchronize) I get the minimal required info LastSync Modified IsDeleted Key, from the API, which I compare with what I have on the client and then send only keys of the rows that don't match to the server to get the entire values that match the keys. But I am not sure about efficiency of this also... not sure how to update the current list with those values efficiently the only way I can think of is using loop in loop to compare keys and update the list, but I know it's not a good approach.
This will never work as long as you do not do the checks on the server side. There is always a chance that someone post between your api get call to server and you post call to server. Whatever test you can do at the client side, you can do it on the server side.
Depending on your DB and other setup, you could accomplish this by adding triggers on the tables/fields that you want to track in the database and setting up a cache (could use Redis, Memcached, Aerospike, etc.) and a cache refresh service . If something in the DB is added/updated/deleted, you can set up your trigger to write to a separate archive table in the DB. You can then set up a job from, e.g., Jenkins (or have a Kafka connector -- there are many ways to accomplish this) to poll the archive tables and the original table for changes based on an ID or date or whatever criteria you need. Anything that has changed will be refreshed and then written back to the cache. Then your API wouldn't be accessing the DB at all. It would just call the cache for the most recent data whenever a client requests it. Your separate service wold be responsible for synchronization of data, database access, and keeping the cache up to date.

How to wait for all machine clients/requests to arrive and give an answer to all during startup/launching time? | Asp.Net Core

I would like to implement something that resemble a temporary requests holder in the server side with Asp.Net Core but I have no idea from where should I start. This holder must wait for three distinguished http requests to arrive (by three distinguished clients). Upon receiving those three requests, the server/api will response to each one of those clients with a simple string and everything should be done during the startup time in client side.
From client perspective, it's quite a simple http request/response task with async/await. But from the server/api perspective I still did not figure it out. Any idea? Would socket be helpful here? ...
Note: This communications here are between machine to machine, no human/browser interaction. N(machine/clients)-to-1(machine/server)
If you want to do a very simple implementation. I would suggest a custom implementation:
Create a table on your database (Transactions with columns: ID,
IsStep1Completed, IsStep2Completed, IsStep3Completed)
On each call you can update the table with each step
Everytime check
if all
three calls are completed
Now, this is an oversimplified implementation. You need also to make sure you cover these cases:
What happens if one call fails? you want to drop the whole transaction?
What happens if two calls are completed, but the third is taking a very long time. Do you want to set up a "time to live" transaction?
If a call fails, Do you want to implement a rollback mechanism?
What if the logic of your application needs more/fewer calls as a transaction?

Asp Net web api 2 response caching (server side)

Is it possible to cache once produced response on server-side and then redeliver it in response to the same request?
Let me explain:
I have an endloint that takes about 5 seconds to generate a response - this includes going to the database and fetching data, processing it, performing some computations on it, serealizing and gzipping the response - the entire thing takes 5 seconds.
Once this is done for the first time I want the result to be available for all the requests coming from all the users.
In my views client side caching, when you either cache the result on the client and do not hit the server at all for some time or when you hit the server but get 304 not-changed instead of the data is not good enough.
What i want is to hit the sever and if this enndpoint (with the same set of parameters) was already called by anyone then get the full response. Is it possible at all?
You have a number of options for this.
One option is API level caching, you create a key using the parameters required to generate the response, you go and fetch the data and save the pair in the cache. Then next time a request comes in, you recreate the key and go and check your cache first. If it's there, happy days, return it, if not, go fetch it and store it.
This of course depends on the amount of data you have, too muchm data or too big data and this will not work. You could also store it for a while, say 10 minutes, 1 hour etc.
If you have a lot of data and caching like this isn't possible then consider something else. Maybe create your own no-sql cache store ( using something like MongoDB maybe ),store it and retrieve it from there, without the need for any changes so it's a straight retrieve, thus very quick.
You could also use something like Redis Cache.
Lots of options, just choose whatever is appropriate.

How do you handle an Async Response from a Web Service

I was given the task of creating a web based client for a web service.
I began building it out in c# | .net 4.0 | MVC3 (i can use 4.5 if necessary)
Sounded like a piece of cake until I found out that some of their responses would be asynchronous. This is the flow ... you call a method and they return a response of ack or nack letting you know if your request was valid. Upon an ack response you should expect an async response with the data you requested, which will be sent to a callback url that you provide in your request.
Here are my questions:
If I'm building a web app and debugging on localhost:{portnum} how can I give them a callback url.
If I have already received a response (ack/nack) and my function finishes firing isn't my connection to the client then over ? How would I then get the data back to the client? My only thought is maybe using something like signalR, but that seems crazy for a customer buy flow.
Do I have to treat their response like a webhook? Build something separate that just listens and has no knowledge of the initial request. Just save the data to a db and then have the initial request while loop until there is a record for the unique id sent from the webhook.... oye vey
This really has my brain hurting :-/
Any help would be greatly appreciated. Articles, best practices, anything.
Thanks in advance.
If you create your service reference, it will generate a *ServiceMethod*Completed delegate. Register an event handler on it to process your data.
Use the ServiceMethod_Async() method to call the service.
The way I perceived your question is as follows, though please correct me if I'm wrong about this:
1) You send a request to their endpoint with parameters filled with your data. In addition, you send a:
callback url that you provide in your request. (quoted from your question)
2) They (hopefully) send an ack for your valid request
3) They eventually send the completed data to your callback url (which you specified).
If this is the flow, it's not all that uncommon especially if the operations on their side may take long periods of time. So let's say that you have some method, we'll call it HandleResponse(data). If you had originally intended to do this synchronously, which rarely happens in the web world, you would presumably have called HandleResponse( http-webservice-call-tothem );
Instead, since it is they who are initiating the call to HandleResponse, you need to set a route in your web app like /myapp/givemebackmydata/{data} and hook that to HandleResponse. Then, you specify the callbackurl to them as /myapp/givemebackmydata/{data}. Keep in mind without more information I can't say if they will send it as the body of a POST request to your handler or if they will string replace a portion of the url with the actual data, in which case you'd need to substitute {data} in your callback url with whatever placeholder they stipulate in their docs. Do they have docs? If they don't, none of this will help all that much.
Lastly, to get the data back on the client you will likely want some sort of polling loop in your web client, preferably via AJAX. This would run on a setInterval and periodically hit some page on your server that keeps state for whether or not their webservice has called your callback url yet. This is the gnarlier part because you will need to provide state for each request, since multiple people will presumably be waiting for a callback and each callback url hit will map to one of the waiting clients. A GUID may be good for this.
Interesting question, by the way.

C# web service method with a transaction commit return

Is it possible to create a web service including a method that performs some operations and then expects a return value/action to commit those operations?
I need a method that returns some values. In the process of returning those values, some data needs to be inserted. After receiving those return values i need to make sure i am able to process them and then commit the initial method.
If the method doesn't receive the flag/commit/whatever, the inserts are rolled back.
Is this possible?
(Sorry if the wording is not clear, hope I'm understable)
I am doing this because i need to get a set of data, that is to slow to be returned with regular SQL. I am planning on zipping that (formatted) data on the server (using a web service), and have the method return it to me in a zipped binary type. If something goes wrong in getting or processing that zipped binary, i need to be able to rollback the entire process.
To accomplish a commit on web service end after receiving web service response with single web service call is not possible, I am afraid. Http web services are stateless, you can make it stateful using sessions. You can make two services one for receiving response and other for performing commit. Between these two calls you can use session if they can help.
Call to receives set of values. You may set a session for next call timeout e.g. You should not start transaction in first call. Just return results. If your results are as per requirement of commit the save data with transaction. You can have some flag in DB records indicating the incomplete transaction in first call and commit or delete it second call and set flag accordingly.
Call for commit based on the first call result and put transaction over here for saving data.
I think you need two web services (if I understand your question correctly). The first one performs the action and returns a value. If the calling program verifies the return value it calls a second web service to perform the commit. Make sense?
I think that the solution should like this.
Method 1 - Create record and return the uid of it. Insert record in pending state
Method 2 - Take parameter of created record and operation (approve or reject). Change the state of the record entered in method1.

Categories

Resources