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.
Related
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.
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.
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
I am creating an app store for digital services. I want the user to be able to choose multiple products with different quantity before confirming the order and pay for the services. This requires that something keep state. From REST Wikipedia:
Each request from any client contains all the information necessary to service the request, and session state is held in the client.
I got state that I need to keep somewhere, and I also have a flow. The flow I can mange, but it is the state that I don't understand how and where I should store. The user may add several products to a shopping cart before checking out.
I have thought of a endpoint like this where you post a cart-item object each time you want something.
POST /shopping-cart
But I shouldn't use HTTP sessions if I understand it right? I have seen someone saying to store it in database but would you use a in memory database then? When should i flush the database if the user doesn't confirm and pay? I could need some input on what I should do to keep it simple and RESTful.
I am using Spring 4.x and Java EE for the record.
But I shouldn't use HTTP sessions if I understand it right?
Correct.
I have seen someone saying to store it in database but would you use a in memory database then?
You should keep in in a disk-storage database. This allows you to add nodes to your server without having to worry about routing all requests from one client to the same node.
When should i flush the database if the user doesn't confirm and pay?
That's a business decision.
Still learning JSP Web Applications here.
I have been doing this for a while in my web application but I would like to know a more secured solution.
Imagine a Table that displays certain Book Information. When user clicks one of the rows in the table,
I basically send the BookID together with the url.
Example URL. http://locathost:8080/myapp/editbook.htm?bookID=3
in my servlet.
String strBookID = request.getParameter("bookID");
I think this is a little weak, is there a way where I could provide a more secure way other than this.
Its quite easier for hacker to edit the URL if I send the BookID together with the URL.
Can you share me some link on how to do this in both the Client Side and Server Side?
Thanks
I think this is a little weak, is there a way where I could provide a more secure way other than this.
You have to define "secure" on the basis of your application. The requirements are totally different for a public website selling books v/s a private library hosting confidential volumes v/s anything other application in between.
At a minimum, you should do the following -
Verify that bookID is in fact an Integer and is within an expected range.
Ensure that you bind bookid in a parameterized SQL Query - this is to prevent SQL Injection.
Show a 'Book not found' page if the book cannot be found
For a public website, the above is enough. You actually want people to discover your books, so if someone modifies the bookID, you shouldn't care.
For a secure library, you have to do a lot more.
Ensure that the URL is protected in web.xml, so only authenticated and authorized users can get to the URL
Verify the current user has access to the bookID. You can store the list of books available to a user in the session object.
If the user does not have access, return a 403 error page.
There are several other strategies to protect URLs; some use tokens to ensure the URL hasn't been manipulated. Others don't send bookID to the client, and instead rely on number {1 through n} where only the server knows that 1 corresponds to Book A and so on. But the idea is to ensure that a user doesn't get access to a book he doesn't have permissions to.
If you are using Spring, I'd highly recommend Spring Security. Otherwise look into JAAS.
You have to suppose that any user can send anything to you. The solution isn't avoiding users to send data in URL, it's to control that they can in fact do the following operation.
You need authentication and authorizations.
How to use authentication with your web.xml
Defining Security Requirements for Web Applications