In Udacity Developing Scalable Apps with Java course, some API methods of the backend application (that conceptually should be HttpMethod.GET) are implemented using HttpMethod.POST.
The following comment is found at the Java documentation:
/**
* Normally this kind of method is supposed to get invoked by a GET HTTP
* method, but we do it with POST, in order to receive conferenceQueryForm
* Object via the POST body.
*/
Does it mean that, even through a HTTPS connection, the JSON form would be sent in plaintext (i.e. not encrypted) if we use HttpMethod.GET?
No. What that means is that this method (whatever it is) is used to retrieve data from the server in response to a request from the client. Normally, when a client is just asking for something, it should use an HTTP GET. HTTP POST requests are intended for sending data to the server.
However, in this case, the client wants to send a (potentially large) object (called conferenceQueryForm) to the server to describe what it wants. That may be too big or cumbersome to do using a GET request, so instead they've used POST.
Related
I want response from one webservice call to be used later on by some other webservice call. How do I implement the code flow for it. Do I have to maintain a session?
I am creating the restful webservices using Spring,java
If user 1 calls an endPoint /getUserRecord and 1 minute later calls /checkUserRecord which uses data from the first call, how to handle it since user 2 can call /getUserRecord before user 1 calls /checkUserRecord
I am using Spring java to create RESTFul webservices.
Thanks,
Arpit
technically you can pass UserRecord from get to check.
GET /userrecords/ --> return the one or more record
POST /checkUserRecord with the record as you want to check as request body.
But I strongly advise you to not do this. Data provided by client are unreliable and cannot be trust by your backend code. What if some javascript has altered the original data ? Besides, what if you have a list of data or heterogenous payload to pass back and forth, it would end up to a complete mess of payload exchanges from client and server.
So as Veselin Davidov said, you should probably stick with clean stateless REST paradigm and rely on identifier:
so
GET /userrecords/ --> [ { "id": 1, "data":"myrecorddata"}, ...]
GET /checkUserRecord/{id} like /checkUserRecord/1
and yes, you will have to make two calls to the database. If your concern is performance, you can set some caching mecanism as piy26 points out, but caching could lead you to other issues (how to define a proper and reliable caching strategy ?).
Unless you manage a tremendous amount of data, I think you should first focus on providing a clear, maintainable and safely usable REST API with stateless design.
If you are using Spring Boot, it provides a way to enable caching on your Repository object which is what you are trying to solve.
#EnableCaching
org.springframework.cache.annotation.EnableCaching
You can use UserID as a hash attribute while creating your key so that response from different users remains unique.
The goal of my app is to create a leaderboard for a competition. To add to one's score, you just have to write something in hipchat (I already have a listener in hipchat that attempts to make a post to my Tapestry app).
I am running into lots of trouble around accepting and handling a 3rd party POST to my Tapestry app. All the documentation I can find deals with internal requests.
Does anyone have any experience in setting up a way to receive a 3rd party post, handle it and make actions with the information? Any help would be great!
Tapestry's native POST handling is intended for handling HTML form submits and is not a good match for machine initiated REST requests. Consequently, I'd handle it as a REST resource request, which JAX-WS is meant for. I assume you mean Tapestry 5 and if so, it's pretty to get started with Tynamo's tapestry-resteasy module (for disclosure, I'm one of the maintainers). If you are new to JAX-WS, you may want to read an overview about it (the link is for Jersey, the reference implementation but the annotations work the same way regardless of implementation). In principle, you'd implement a (POJO+annotations) resource class and an operation with something like this:
#POST
#Produces({"application/json"})
public Response scorePoints(User user, long score)
{
leaderboardService.add(user, score);
return Response.ok().build();
}
On the client side, you'd just pass in the user ID and Tapestry's type coercion would handle the rest (assuming User is a known entity to Tapestry). Of course, you could just use primitive data types on both sides as well.
I am currently using a #POST web service to retrieve data.
My idea, at the beginning, was to pass a map of parameters. Then my function, on the server side, would take care of reading the needed parameters in the map and return the response.
This is to prevent having a big number of function almost identical on the server side.
But if I understood correctly, #POST should be use for creation of content.
So my question: Is it a big programming mistake to use #POST for data retrieval?
Is it better to create 1 web service per use case, even if it is a lot?
Thanks.
Romain.
POST is used to say that you are submitting data.
GET requests can be bookmarked, POST can't. Before there were single page web appliations we used post-redirect-get to accepta data submission and display a bookmakable page.
If you use POST to retrieve data then web-caching doesn't work, because the caching code doesn't cache POSTS, it expects POST to mean it needs to invalidate its cache. If you split your services out use-case-wise and use GET then you can have something like Squid cache the responses.
You may not need to implement caching right now, but it would be good to keep the option open. Making your services act in a compliant way means you can get leverage from existing tools and infrastructure (which is a selling point of REST).
doGet();
Called by the server (via the service method) to allow a servlet to handle a GET request.
doPost()
Called by the server (via the service method) to allow a servlet to handle a POST request.
No issues with them.Both will handle your request.
For my program I have a Server class and a Protocols class.
When my Server receives a message from the Client I want the Server to send the message to the Protocols. The Protocols then figure out what needs to be done with the message and invokes the proper methods. Now, the methods that need to be invoked are inside the Server.
So essentially, the Server needs to have access to the Protocols and the Protocols needs to have access to the Server.
What is the best way to establish such a relationship? How would I do it?
I don't want a circular reference, but is there another way?
What about following the Servlet model of request/response objects?
Every time you receive a message, you package it up in a request object, and you create a response object, and send it to you protocol handler (acting as a kind of servlet).
Your handler, deals with the request, and whatever it needs to pass back, it puts it in the response object, which is ultimately used by the server to send the actual response to the client. If the server needs to take any decisions, it can do it based on the information already provided in the response object after the request has been attended by your protocol handler.
You may later add similar concepts to those of the servlet model, like filters or event handlers to deal with similar requirements.
In my app I have, for example, 3 logical blocks, created by user in such order:
FirstBlock -> SecondBlock -> ThirdBlock
This is no class-inheritance between them (each of them doesn't extends any other), but logical-inheritance exists (for example Image contains Area contains Message). Sorry, I'm not strong in terms - hope you'll understand me.
Each of blocks sends requests to server (to create infromation about it on server side) and then handles responses independently (but using same implementation of http client). Just like at that image (red lines are responses, black - requests).
http://s2.ipicture.ru/uploads/20120121/z56Sr62E.png
Question
Is it good model? Or it's better to create a some controller-class, that will send requests by it's own, and then handle responses end redirect results to my blocks? Or should implementation of http client be controller itself?
P.S. If I forgot to provide some information - please, tell me. Also if there a errors in my English - please, edit question.
Here's why I would go with a separate controller class to handle the HTTP requests and responses:
Reduce code duplication (do you really need three separate HTTP implementations?)
If/when the communication protocol between your app and server changes, you have to rewrite all your classes. Say for example you add another field to your response payload and your app isn't built to handle it, you now have to rewrite FirstBlock, SecondBlock, and ThirdBlock. Not ideal.
Modify your Implementation of HTTP client controller class such that:
All HTTP requests/responses go through it
It is responsible for routing the responses to the appropriate class.
Advantages?
If/when you change the communication protocol, all the relevant code is in this controller class and you don't have to touch FirstBlock, SecondBlock, or ThirdBlock
Debugging your HTTP requests!
I would suggest that your 3 blocks not deal with HttpClient directly. They should each deal with some interface which handles the remote connection sending of the request and processing of the results. For example:
public interface FirstBlockConnector {
public SomeResultObject askForSomeResult(SomeRequestObject request);
}
Then the details of the HTTP request and response will be in the connector implementations. You may find that you only need one connector that implements all 3 RPC interfaces. Once you separate out the RPC mechanisms then you can find common code in the implementations that actually deal with the HttpClient object. You can also swap out HTTP with another RPC mechanism without changing your block code.
In terms of controllers, I think of them being a web-server side term and not for the client but maybe you meant a connector like the above.
Hope this helps.