Backend transactions with REST API - java

I have a question on REST API and how to create some back-end transactions in our application.
We have an accounting application, and so for every transaction created there is a ledger entry. (though client - javascript is unaware of such entries)
For instance, in REST we create a transaction through -
POST /transactions/
(or)
POST /accounts/1223/transactions/
Now, when I deal with this in RestController,
I want to do the following -
Create the Transaction based on POST.
Create a ledger entry in the back-end. (Client - javascript should be unaware)
Update the balance entry on the account. (Client - javascript should be unaware)
In the TransactionService in spring java app (this should be immaterial though, as my question is focused on REST API semantics),
#Transactional
public void saveTransaction(Transaction t) {
transactionRepo.save(t);
Ledger l = new Ledger(<particulars>)();
ledgerRepo.save(l);
Balance b = balanceService.get(<partiulars>);
balanceRepo.update(b);
}
I am confused with the REST API approach as they only update the
resource. Doesn't updating a resource change other underlying particulars in the application?
Reading about REST confuses on how transactions atomicity is
tackled. What is the solution for such activities in REST?
I cannot do these multi-saves from the client (javascript) using multi-phase approach (saving transaction first, then with transaction id creating ledger etc) as the client application should be unaware of such back-end service-related actions.
Could someone explain clearly in this particular scenario how to approach?
Many applications are finance and accounting related, but I just don't get why REST won't fit for such practical scenario. Might be my understanding is different.

when I deal with this in RestController, I want to do the following -
Create the Transaction based on POST.
Create a ledger entry in the back-end. (Client - javascript should be unaware)
Update the balance entry on the account. (Client - javascript should be unaware)
That all seems pretty reasonable.
I am confused with the REST API approach as they only update the resource.
So my diagnosis is that you are a victim of semantic diffusion; how much did the meaning of REST change before you learned it?
Your best starting point may be Jim Webber's 2011 talk
You have to learn how to use HTTP to trigger business activity as a side effect of moving documents around the network.
HTTP tells you what the semantics of the requests are -- that's what REST calls the "uniform interface" -- but it doesn't say anything about the side effects. The fact that, in your domain, you respond to a POST request by updating ledgers and balances is fine.
If it helps: it's exactly the same way a web site works. You fill in a form and submit it, and some web page (resource) changes as a result, but also a bunch of interesting things happen on the back end.

Related

Persisting related data after client has completed some web service calls in a chain

Consider that our application has some configs that user set them, and we need to have a backup of those data in order to restore them later.
Configs are list of different Objects and I have created some web services for each List of Object and application calls them in a chain, it means that with getting success response from one service they call the next one.
Now what the problem is...
I need to store each services data somewhere and after finishing the last service call in front end, I will create the final Object with received data from client and persist it in database(here MongoDB).
What is the best way for implementing this strategy?, consider that I don't want to persist each List of Object per service, I need to persist whole Object once.
Is there any way for storing body of a request somewhere until other services to be called?
What is the best for that?
I will appreciate any clue or solution that help me!
BEST WAY:
store all objects in client side and send only one request to server.
it reduces resource usage of server side.
ALTERNATIVE:
if you realy want to handle it by several requests (which I do not recommend it) then one strategy is : store objects of each request by an identifier related to that session (best candidate is JSESSIONID) to a temporary_objects_table and after final request store it in main tables.
and in failure of any service for that session, remove records with that sessionid from temporary_objects_table.
it has much more complexity comparing first approche.
After some research I found my answer:
REST and transaction rollbacks
and
https://stackoverflow.com/a/1390393/607033
You cannot use transactions because by REST the client maintains the client state and the server maintains the resource state. So if you want the resource state to be maintained by the client then it is not REST, because it would violate the stateless constraint. Violating the stateless constraint usually causes bad scalability. In this case it will cause bad horizontal scalability because you have to sync ongoing transactions between the instances. So please, don't try to build multi-phase commits on top of REST services.
Possible solutions:
You can stick with immediate consistency and use only a single
webservice instead of two. By resources like database, filesystem,
etc. the multi phase commit is a necessity. When you break up a
bigger REST service and move the usage of these resources into
multiple smaller REST services, then problems can occur if you do
this splitting wrongly. This is because one of the REST services will
require a resource, which it does not have access to, so it has to
use another REST service to access that resource. This will force the
multi phase commit code to move to a higher abstraction level, to the
level of REST services. You can fix this by merging these 2 REST
services and move the code to the lower abstraction level where it
belongs.
Another workaround to use REST with eventual consistency so you can
respond with 202 accepted immediately and you can process the
accepted request later. If you choose this solution then you must be
aware by developing your application that the REST services are not
always in sync. Ofc. this approach works only by inner REST services
by which you are sure that the client retry if a REST service is not
available, so if you write and run the client code.

System Design: How can I design a RESTful API that allows querying of results asynchronously

I need to build a /search API that allows someone to send a POST, and retrieve an ID that can be queried later via a seperate /results API.
I've looked at Spring methods:
DeferredResult
#Async
but neither seem to demonstrate returning an ID from a search. I need to have a system that can remember the ID and reference it when someone calls the /results API to retrieve specific results for a search.
Are there any examples of a Spring application doing this
You must remember that Restful services are stateless, therefore It won't be a good practice keeping your search results states in the server.
One solution could be storing your search states on a Database (SQL/NoSQL) and using the Spring Cache support to improve response times.
When an user requests a new search using /search, on the server you must generate the ID, prepare your results and persist it on the database, then you send the new ID to the client. Later the client must request its results using /results/{searchId}.
Please let me know if you'll use this possible solution and I'll share you an example on Github

Is stateless authentication adapted to a per-user database connection?

The issue
I'm working on an application, which, as many applications, starts with a login page before showing any kind of data.
The problem is that my client specifically requested that the credentials entered should be used to access the database.
This means that, instead of running the username / password against a "user" table, they will be used to acquire the user's database personal access.
It was decided by my superiors that this application would be build on top of a SpringBoot skeleton, which happens to be using a Stateless JWT Authentication mechanism.
I'm no expert when it comes to comparing the benefits of Stateless vs Stateful, but if I understood the concept correctly, this means that my application will need to re-establish the database connection with every single request, right?
I'm asking this because we are experiencing very slow response times.
The code seems to hang a little while on database setup related code, such as
dataSrc.getConnection();
or
entityManagerFactoryBean.afterPropertiesSet();
A possible solution?
I've heard of Hibernate's StatelessSession, but I was unsuccessful in setting it up.
I'm not even sure it would help at all, but from what I read, it uses a lower level Hibernate API, which might help mitigate the problem, without much of an impact on the way things are already coded since the SQL operations are exclusively stored procedure calls, which are manually mapped to Java objects.
What I need help with
Basically, I just want answers to 3 questions :
Question 1 :
Should I simply revert to Stateful authentication, because Stateless models are unadapted to my use case scenario?
Question 2 & 3 :
Can StatelessSession system even be implemented in my scenario, and would it make a significant difference on the database connection time?
But, of course, if you know of any other lead that my help me solve my problem without having to revert the whole thing to Stateful, I'm taking it!
Finally got time to answer this (in case someone passes by in the future).
Basically, I had two choices : remove Hibernate altogether or "go back" to Stateful sessions.
I went with the first option, wich I could do only because we had no annotation based mapping between our java objects and our database.
Going Stateful might have been a better approach, but i didn't really know how to do that. I found an impressive amount of articles underlining how to go Stateless, but not how to go back Stateful and... Well... Doing it backward wouldn't be enough, since I would be missing a lot of configuration, so I'd have to research it, and it was a hassle I had no time to deal with.
Using a custom implementation of org.springframework.web.filter.GenericFilterBean, I wrap every incoming request in a custom requestWrapper containing the database connection.
I open / create said connection using the java (low) API : java.sql.DriverManager.getConnection
I can then retreive this connection from my wrapper, wich is vehiculated through the application by Spring by using this code :
ServletRequestAttributes att = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes());
ContentCachingRequestWrapper springWrapper = (ContentCachingRequestWrapper) att.getRequest();
CustomWrapper myWrapper = (CustomWrapper) springWrapper.getRequest();
myWrapper.getConnection();
Just don't forget to properly close everything to avoid memory leak and you're set.
One would also need to register the driver properly, just by calling the constructor of said Driver in the application main class.

How to Deal with transactions in RESTful web services?

A REST client goes through a sequence of steps with a server in a flow. The client would like to cancel the flow and undo all the changes done to the data in that flow.
For example, we have a below method. It has three different steps in it. First two are rest calls where third one is data insertion. Now if restCall1(), restCall2() are success but third step is failed. Everything done in first two steps should be reverted back.
method(){
restCall1(); // Rest Call to the server, perform DB operations
restCall2(); // Rest call to the server, perform file operations
insertData(); // Perform DB operations
}
What is the best practice to deal with this transaction problem. One way is to build a custom transaction framework and rollback steps. Is there any framework/tool that can give solution to deal with this problem?
A REST client can only maintain it's own state in REST call and there is no synchronization between state of REST client and resources managed by server.You will have to maintain the synchronization among the various REST calls to web service which violates the stateless communication.If you intend to do that you have to maintain the synchronization of states among the various REST calls and co-ordinate accordingly.
More here
However there are workarounds.Retro is a model which supports the transactions for REST in an error prone and scalable way.
See this as well.Hope it helps.

Managing state in RESTful based application

We are evaluating the technology to be used for a web based application and some suggestions are to go with RESTful based services approach.
Tech Stack
1) Spring
2) Apache CXF ( JAX-RS)
My questions are
1) How state is managed between requests. For example, a user has been authenticated and now he is making a series of requests lets say going through a paginated report. I would imagine the URL for this will be like
domain.com/reports/customreport/page/1
domain.com/reports/customreport/page/2
etc...
a) Where is the user information & request parameters are stored so that it can be shared between requests.
b) Lets say the result is being streamed, where is Rowset is stored?
Is there a complete sample application something similar to Petclinic that can provide the best practices for such an application.
If you are doing RESTful strictly / properly, then user authentication is done in each request and there is no concept of a session. Each request contains enough context information (in the URL and/or request parameters) to allow it to work independent of a session.
1) How state is managed between requests.
It must be managed by the client.
a) Where is the user information & request parameters are stored so that it can be shared between requests.
User authentication information is stored by the client and provided to the server with each request. The server will recalculate any derived information about the user on each request. Any request parameters that would normally be stored in a server-side "session" must be passed afresh with each request.
b) Lets say the result is being streamed, where is Rowset is stored?
In the first instant, nowhere. The query is reissued each time with a parameter saying where to skip to. If performance was an issue, you could
read-ahead a few pages of the result set and store them in a server-side cache, or
tune the database query caching for the query.
1) The user information is not stored anywhere, the user has to send his credentials (or whatever authentication method you're using) on every single request.
2) Streaming doesn't make much sense in a RESTful API, if you would like to do streaming I'd greatly advice you to look for something like WebSockets (in Java you can easily do this with Jetty)
If you said streaming but you meant paginated results, same as 1, there is no state kept, the client has to send a new request with all the information and the server has to query the database (or go to a cache, or do anything needed) and return the result to the customer.
You should also read more about REST, as your question is quite vague, one good start is the Restful Web Services book or, if you feel adventurous, you can try Roy Fielding dissertation that defined what we call REST today.

Categories