I am new to restful services and willing to get some ideas from the experts.
The application which will be accessing my service is having a datatable-grid (each row of the grid represents an Employee Object/Entity) where user can delete more than 1 records at a time(based on the number of checkbox selected by the user). In such kind of a delete operating how will be the URL representation and how will the data be send to the service?
My Idea
Since the number of rows deleted by the differs (based on the number of checkbox selected by the user), hence I am opting for the query string and below will be the URL representation using which I can get the data in my service:
/deleteEmployees?id=1,2,3
i.e. a comma seperated values of the id's which will uniquely identify a record in the table.
Based on my Idea, I have a few questions:
1) The query String mentioned above contains of comma-seperated values (i.e. Ids). Is it a valid URL where query strings will contain this kind of values?
2) Is there any restrictions in defining the query strings of an URL (like the way I did using csv)?
3) Any other alternative of achieving the same in a better and efficient manner?
P.S. I am new on this and hence looking for different ideas from the experts and try to understand what is correct and what is not.
A comma separated list of Employee ids is a fine way to do it, but I wouldn't put it in a URL with an action in it, ie. /deleteEmployees?id=1,2,3. REST is more about identifying resources, rather than actions, in URLs. I would either loop through each one of the employee ids to delete and send an HTTP DELETE request for each
DELETE /employees/1 HTTP/1.1
DELETE /employees/2 HTTP/1.1
DELETE /employees/3 HTTP/1.1
Another alternative is to send one HTTP DELETE request to a URL like /employees, keeping the suggested REST identification of resources and using HTTP methods. You would pass the list of ids in an HTTP header.
DELETE /employees HTTP/1.1
Employees-To-Delete: 1,2,3
Take a look at this answer for character restrictions in URLs.
Related
I am trying to build a Spring REST Read operation using spring boot. Typically for all read only operations preference should be HTTP GET only.. (at least as far as I know)
Scenario: Client will be sending a list of UUID(assume it as employeeID) values to read employee data. Here Client has a provision to select a bunch of employees and read the data.
Once request is received I need to iterate through those IDs and invoke an existing third party service which will give me the employee data.
Once all UUIDs are processed a report will be generated for all those selected employees.
List of items I would like to hear from you all is..
How to achieve GET operation here when incoming IDs are more than HTTP GET URI limit. Because if the IDs are 100 then the URI is going to reach the limit.
Please request to not suggest for HTTP POST because of few limitations in the requirement.
Any references for handling this scenario asynchronously is much appreciated.
If you suggest to store the IDs first into a table and process them later.. Sorry this is not something what I am looking for. Because client need this data in less than 10 seconds.. (approx)
How to achieve GET operation here when incoming IDs are more than HTTP GET URI limit. Because if the IDs are 100 then the URI is going to reach the limit
Instead of sending these IDs in URI, add these IDs in request body send with GET request.
HTTP GET with request body
You can totally send the UUID's as a request body with GET call. It works just fine.
Ok you are very restricted but I can see that there are two ways to face it, group them or send them by parts then my suggestions are:
I read number 4 but you can improve your requests and time execution sending async requests, then you can send a segment with a ID and total of UUID's to get all information in a short time in server, then you could process it.
Make segments of UUID's to identify them by groups and not individually, then your UUID's will be few.
I don't know if you can get a "selected event" with a check box to send a request for every event, when user sends "generate report event" then you has all data in server.
I want to build my application RESTFul.
Whats the normal URI concept for subObjects.
My Example:
I have a some users. I get a user by /users/:id. Now this user can be rated. Is the best concept to do the userRatings (GET,POST,PUT,DELETE) over /users/:id/ratings or handle them as an own object over /ratings/. Or a mix of both?
My questions:
When it is /ratings/ how i get a list of ratings for a specific
user (/ratings/?userId=1?).
Is the object normally in the URI plural or not?
The URL scheme depends largely on what you need to do with your data model, e.g. how you want to query those ratings:
if you only ever want to display a single user's ratings, put them under /users/:id/ratings
if you want something like "10 top-rated users", consider something like GET /users?toprated -- here you're looking for users, so the URL should signify that by being /users
if you want to get ratings across several users, e.g. to find all ratings containing the word "outstanding", /ratings/ makes more sense: The search is then naturally expressed as GET /ratings?q=outstanding -- here you want ratings so the URL should be /ratings plus a request parameter to restrict what kind of ratings you want
In either case, unless you're building a huge, public API and expect lots of clients right on launch day, go with what works and change the URL scheme if you need to.
As for the singular/plural debate: Use plural for path segments, i.e. /users, /ratings because it follows naturally from REST's building blocks of a "resource" and "collections of resources": There's the collection of users at /users (accepting GET, POST) and there's a single user at /users/:id (accepting GET, PUT, DELETE).
I am curious if there is a way to store some user data on my request which will come back to me on the returned data. For example, I am sending several requests for let's say 3 different orders. They might be for the same symbol, but depending on the order I will be getting different types of data. Is there a way that I store the order ID on the outgoing message request and have it come back to me on the return? I see there is a Session.sendRequest call where you can specify a requestLabel, but I don't see it coming back on the returned message so I'm not sure what this is for.
Thank you in advance!
It looks like the correlation ID is exactly what is needed. I can create a unique correlation ID for each order request based on the order ID and some unique string (for me, a count is sufficient). Then I can parse out the order ID piece when it is returned. I'm still not fully sure what requestLabel is for, but I don't think I need it for this requirement.
I think it'd be up to you and your app, not Bloomberg. I'll bet Bloomberg is idempotent - it treats every request that comes in as if it's the first one ever.
The Session is a variable on your side that's created when a user logs in. You'd create the label or some other unique tracking GUID and keep it in session. Every request that user sends out during that Session would be associated with that session ID>
I use GWT for UI and Hibernate/Spring for buisness-layer.Following GWT widget is used to display the records.(http://collectionofdemos.appspot.com/demo/com.google.gwt.gen2.demo.scrolltable.PagingScrollTableDemo/PagingScrollTableDemo.html).I assume the sorting is done in client side.
I do not retrieve the entire result set since its huge.
I use
principals = getHibernateTemplate().findByCriteria(criteria,
fromIndex, numOfRecords);
to retrive data.Theres no criteria for sorting in Hibernate layer.
This approach does not give the correct behaviour since it only Sorts the current dataset in the client.
What is the best solution for this problem?
NOTE : I can get the primary-Sort-column and other sort Columns using the UI framework.
May be I can sort the result using primary-sort-column in the hibernate layer?
You need to sort on the server.
Then you can either:
send the complete resultset to the client and handle pagination on the client side. The problem is that the resultset may be big to retrieve from db and sent to the client.
handle the pagination on the server side. The client and the server request only one page at a time from the db. The problem then is that you will order the same data again and again to extract page 1, page 2, etc. each time you ask the db for a specific page. This can be a problem with large database.
have a trade-off between both (for large database):
Set a limit, say 300 items
The server asks the db for the first 301 items according to the order by
The server keept the resultset (up to 301 items) in a cache
The client request the server page by page
The server handles the pagination using the cache
If there are 301 items, the client displays "The hit list contains more than 300 items. It has been truncated".
Note 1: Usually, the client doesn't care if he can't go to the last page. You can improve the solution to count for the total number of rows first (no need of order by then) so that you can display message that is better to the user, e.g. "Result contained 2023 elements, only first 300 can be viewed".
Note 2: if you request the data page by page in the database without using any order criterion, most db (at least Oracle) don't guarantee any ordering. So you may have the same item in page 1 and 2 if you make two requests to the database. The same problem happens if multiple items have the same value that is use to order by (e.g. same date). The db doesn't guarantee any ordering between element with the same value. If this is the case, I would then suggest to use the PK as the last order criterion to order by (e.g. ORDER BY date, PK) so that the paging is done in a consistent way.
Note 3: I speak about client and server, but you can adapt the idea to your particular situation.
Always have a sort column. By default it could by "name" or "id"
Use server side paging. I.e. pass the current page index and fetch the appropriate data subset.
In the fetch criteria / query use the sort column. If none is selected by the client, use the default.
Thus you will have your desired behaviour without trade-offs.
It will be confusing to the user if you sort on a partial result in the GUI, and page on the server.
Since the data set is huge, sending the entire data set to the user and do both paging and sorting there is a no-go.
That only leaves both sorting and paging on the server. You can use Criteria.addOrder() to do sorting in hibernate. See this tutorial.
I have a struts2 application with a single page that may show one of a number of values stored in a database. The application is for a school with many departments and each department has many programs. The department page is accessed using a url like this
department.action?id=2
and the DepartmentAction will load the Department with id = 2 for display. All this is fine if the user is just browsing around the site but it gets uncomfortable if I want to provide a link to say the Engineering department in the newspapers. The link will have to be www.myschooldomain.com/department.action?id=2. I see a number of problems with this.
First, it is not user friendly. Second, it is prone to be broken because the departments are dynamically maintained and the id for a department could change without warning making the link unstable.
I would prefer to print a url like this: www.myschooldomain.com/department/engineering and have that somehow go to department.action?id=2.
My thoughts so far: create an action that will parse the url for the department name at the end then look it up by name. Maybe I could add a friendlyurl field to the database for each department.
But the question is: Is there a better way to do this in struts2?
Thanks.
Update (May 2009): I just happened to stumble back over this question and thought that I would say what I did to solve it.
I created a new package in the struts.xml called departments. In this package there is only one action mapped to *. So it catches all requests to mydomain.com/departments/anything.html.
In the action class I simply parse the url and look for the part between departments/ and .html and that is the name of the department so I can do a lookup in the database for it. This has been working fine for almost 5 months now and I have implemented it for other areas of the site.
You could use the URL Rewrite filter
This avoids the need for any additional servlet or Java code but requires XML descriptors.
This is normally done by mapping a servlet to, in your case '/department', and then using the path information (e.g., '/engineering') within the servlet to determine the ID.
Since the Struts2 dispatcher doesn't implement this behavior, it might be simplest to write your own servlet. This servlet would be configured with a map of valid "friendly" names to the unfriendly numeric identifiers. This could be an actual Map or it could be done with a database finder method.
The result of getPathInfo() would be used to look up the ID, and the request would be forwarded to the department.action. Handle the null case too, which means the user is trying to browse the /departments/ directory.