I'm planning to develop a webservice, and I like to try the RESTful architecture. The issue is that I don't know if the service is adequate for it, or it is better to use SOAP.
The service is about downloading some data from the server to a device on the local computer. The data will be split into chunks. The service will be run with an ad-hoc client at the local machine that will manage the device the file is gonna be stored in.
I was thinking on having something like:
/files/{id} --> will inform about the details of the file
/files--> list all the files
The problem is for the action. In rest only GET, POST and (PUT DELETE) are defined. But I want to have something like download. My idea, although not fully restful is to create:
/files/{id}/download
This will return something like
{ "chunk" : "base64 string with chunk data"
"next" : "http://XXX/file/id/download?chunk=1
}
When next is empty the whole set of chunks would be downloaded.
What do you think? Is it ok to do it this way or would it be better the traditional way using SOAP and defining functions like getFiles(), getFileChunk(chunkNo, file)?
Any comment is really appreciated.
See you
If using REST, you don't need to define your own "chunking" protocol as the HTTP headers Content-Length, Content-Range and Transfer-Encoding are all used for sending chunked data.
See the RFC for HTTP header fields
As John already mentioned you might want to separate between your file resources and the file resource metadata (any information about your file). Additionally a more RESTful way to access your chunks could look like this:
http://url/files/{id}/chunks
{
"complete" : false,
"chunks": [
"http://url/files/<fileid>/chunks/1",
"http://url/files/<fileid>/chunks/2",
"http://url/files/<fileid>/chunks/3",
]
}
Basically, here, you return a list of RESTFUL URIs to all your file chunks and the information if all chunks of the file are already complete. I don't see that SOAP might have any advantage there since you would define the same methods (getFile and getChunks) that are already covered by the REST verb GET.
It sounds like you really have two different resources: file-metadatas and files. What about something like:
/file/{id} // GET: Retrieve this file's data.
/file-metadata/{id} // GET: Metadata about a particular file. Contains link to file:
// {
// ...
// data: "http://.../file/156", // Where to find file's data.
// }
/file-metadata // GET: List metadata for all files.
Related
I am trying to test my Springboot App using jMeter. I want to send multiple request with some JSON payload to receive the response concurrently (via threading).
While doing this, in order to check validity of response, I want to keep a log where it can show the request-response pair (side-by-side or even in separate files, they should just be identifiable which request gave which response).
This is to test if one request is not tampering other request's response (data validation).
I have already tried Simple Writer tool where we can log request and response (I think jmeter have used some different terminology in menu) on configure menu. But it doesn't seem to be working when I run the results.
So my main concern is how can we store the JSON request data and response data pair somewhere after test iteration have completed. I have never used jmeter before so a little bit of detailing will help.
Thanks!
You can use Flexible File Writer which gives you the full freedom with regards to what and where to store.
For example if you configure the Flexible File Writer as:
I'll provide textual form of the sample template:
---------REQUEST----------------------\r\n|requestData|\r\n---------RESPONSE--------------------\r\n|responseData|\r\n-------------------------------------
You will get results file looking like:
---------REQUEST----------------------
POST https://jsonplaceholder.typicode.com/posts
POST data:
{
"title": "foo",
"body": "bar",
"userId": 1
}
[no cookies]
---------RESPONSE--------------------
{
"id": 101
}
-------------------------------------
You can install Flexible File Writer plugin using JMeter Plugins Manager
Check out the JMeter docs on configuring the Results Tree. It will show you the results and you can configure how much to keep and where.
https://jmeter.apache.org/usermanual/component_reference.html#View_Results_Tree
In particular you might benefit from this:
https://jmeter.apache.org/usermanual/component_reference.html#Save_Responses_to_a_file
I am writing a REST API in JAX-RS 2.0, JDK 8 for the below requirement
POST API /server/fileUpload/ (Multipart Form data) where I need to send a Big .AI (Adobe Illustrator) File in this.
The Server, takes the file and return Status 202 (Accepted), Acknowledging that file transfer happened Successfully. (From endpoint to Server)
Now at the Server, I am using Java + Imagemagik to convert .AI File (20-25 MB File) to small JPG Thumbnail, place on a Apache HTTP Server and share the location (like http://happyplace/thumbnail0987.jpg)
Now the Second Response should come from Server with Status 200 OK and Thumbnail URL
is it feasible with one REST API? (Async/similar)
or should I split it to 2 API calls, Please suggest
No. In http, one request gets one response. The client must send a second request to get a second response.
You can use WebSockets for that.
If you are calling from script the call will be async you can handle the Thumbnail URL when you get a response. When you are calling from java program i suggest to run it on a different thread, If the execution is not sequential i.e ( Remaining lines can be executed without getting URL). If url is needed for the remaining section of code you can make one call and wait for the response then execute remaining code.
You need to make different APIs for both scenarios. One for showing file upload status and another for all file conversion and manipulation.
On the client side second request must be callback of first request.
The best way to handle these kind of scenario is to use Java Reactive (Project Reactor, WebFlux).
You can return two response using custom middlewares in asp.net (however not recommended).
Return response from one middleware and subsequently you can invoke next middleware and return second response from second middleware
I went to a open lecture about Jersey REST web service and made some notes. Here is what the lecturer said in the lecture, I am quite confuse about it.
i.you will need POST some content to /files/. For example, you
have a file locally called data.json.Posting the content of that file
to your REST service will store the content on the server with a name
it chooses automatically, say 3.json, in a folder chosen by you.
ii.The key thing here is the REST service will need to manage the
files it creates by choosing a name that hasn't been used and return
that name to sender, so the sender can re-download the content it sent
using the name it gets.( The sender do not know which name the content
will be given until it receives the response from the REST service).
For step i, is that means upload a file to the service and save to a new location? What is mean by the service will give it a name automatically?
For step ii, is that means if I send three files into the service, when I call GET /files/1, GET /files/2 and GET /files/3 will return the content of 1.json, 2.json, 3.json respectively? Besides the lecturer said we can use curl command line to post a file to the service.
The lecturer did not provide any example, which made me not understant it clearly.
Is it possible to help me to write a demo about that or provide some examples to me?
you have a file locally called data.json
Alright, simple enough
Posting the content of that file to your REST service will store the content on the server
Sure, saving files. It reads that POST data, and stores it to disk.
a name it chooses automatically
This is a minor detail... It could be stored as the same name, but then you'd have conflicting filenames.
in a folder chosen by you
That point isn't really clear... but, moving on.
the REST service will need to manage the files it creates by choosing a name that hasn't been used
Exactly the earlier point.
and return that [...] to sender
Think about a typical website... You request http://stackoverflow.com. It returns back HTML. Your REST service is just returning a string / file.
return that name to sender, so the sender can re-download the content it sent using the name it gets.( The sender do not know which name the content will be given until it receives the response from the REST service).
The client needs to know the name of the file that was added. Otherwise, you don't know how to request the file; the server had generated its own name for the file you sent to it originally.
if I send three files into the service, when I call GET /files/1, GET /files/2 and GET /files/3 will return the content of 1.json, 2.json, 3.json respectively?
Not quite - The server generated the names of the files. So, a better example would be
POST -d file.json /files
Outputs the text
20160801-21-38.json
And in order to request that file back, you now need to use that value
GET /files/20160801-21-38.json
My main question is how can I pass JSON as well as File to post request to REST API? What needs in Spring framework to work as client and wait for response by passing post with JSON and File?
Options:
Do I need to use FileRepresentation with ClientResource? But how can I pass file as well as JSON?
By using RestTemplate for passing both JSON as well as File? How it can be used for posting JSON as well as File?
Any other option is available?
Sounds like an awful resource you're trying to expose. My suggestion is to separate them into 2 different requests. Maybe the JSON has the URI for the file to then be requested…
From a REST(ish) perspective, it sounds like the resource you are passing is a multipart/mixed content-type. One subtype will be application/json, and one will be whatever type the file is. Either or both could be base64 encoded.
You may need to write specific providers to serialize/deserialize this data. Depending on the particular REST framework, this article may help.
An alternative is to create a single class that encapsulates both the json and the file data. Then, write a provider specific to that class. You could optionally create a new content-type for it, such as "application/x-combo-file-json".
You basically have three choices:
Base64 encode the file, at the expense of increasing the data size
by around 33%.
Send the file first in a multipart/form-data POST,
and return an ID to the client. The client then sends the metadata
with the ID, and the server re-associates the file and the metadata.
Send the metadata first, and return an ID to the client. The client
then sends the file with the ID, and the server re-associates the
file and the metadata.
Basically I need to provide REST service that would receive a String param, use that param to fetch a file from another system and then return the fetched file back as the response.
The effect should be the same as when a user clicks on a pdf or any other binary file link and the browser prompts him to save/download that file.
A couple of points:
is it possible to stream the file (to send bytes as I receive them from source system). In other words, how to handle very large files?
also related to streaming, when using regular HttpServletResponse, do I have to wait until a large file is completely read to return response.build()?
How do I go around doing this using Apache Wink?
PS Sorry, this may be trivial for Wink gurus, but I'm just starting to wrap my head around developer guide.
You can just return the java.io.File from your method. You can wrap it with Response if you like. Wink will handle the streaming. The streaming doesn't start when you call to response.build(), but rather when your method finishes.
If you want a correct download dialog, you should return the proper Content-Disposition header. See How to set response header in JAX-RS so that user sees download popup for Excel?