Pluralized Rest Resources - java

I want to create a new rest resources that searches an entity in database. I have to make the request as POST since there is a complex criteria passed in a request body.
I created my resource endpoint as /search, however, I learned that resources should be always pluralized. In this case, should I be naming as /searches? I want to know if /searches is a standard naming convention?

No, I have never heard that resources should always be pluralized. I would say /search is appropriate here. For example, if you do a search on google or msn, you'll see that they use /search for their searches.
Hopefully this helps.

Related

How to handle filtering in restlet resource

Hi i am pretty new to Restlet, and generally building web servers. I need to support filtering like this:
http://deviceip:port/resource?id=id
So far i know how to return a json message when user invokes different resources, based on my web server state. I would attach it to router, and add class which handles that resource. But how can i return only one resource from collection based on id? What i need to change in my class which is responsible from handling of that resource. Also how can i attach this resource to router? Any help is welcome, if you can write some code snippet to help me, that would be great.
Thanks
So as i understand you can approach to this in two ways. One is explained by link above and another one is using query. So basically you font have to create another resource like in the answer from link above, instead you can just extract query with this.getQuery()
and than call method getFirstValue("id"), which will return entered id.

Restful service naming conventions?

For a restfull service, does the noun can be omitted and discarded?
Instead of /service/customers/555/orders/111
Can / should I expose: /service/555/111 ?
Is the first option mandatory or are there several options and this is debatable?
It's totally up to you, I think the nice thing about having the nouns is that it helps you see from the URL what the service is trying to achieve.
Also taking into account that under customer you can have something like below and from the URL you can distinguish between order and quote for a customer
/service/customers/555/quote/111
/service/customers/555/order/111
One of the core aspects of REST is that URLs should be treated as opaque entities. A client should never create a URL, just use URLs that have been supplied by the server. Only the server hosting the entities needs to know something about the URL structure.
So use the URL scheme that makes most sense to you when designing the service.
Regarding the options you mentioned:
Omitting the nouns makes it hard to extend your service if e.g. you want to add products, receipts or other entities.
Having the orders below the customers surprises me (but once again, that's up to you designing the service). I'd expect something like /service/customers/555 and /service/orders/1234567.
Anyway, the RESTful customer document returned from the service should contain links to his or her orders and vice versa (plus all other relevant relationships).
To a certain degree, the "rules" for nameing RESTful endpoints should follow the same naming rules that "Clean Code" for example teaches.
Meaning: names should mean something. And they should say what they mean, and mean what they say.
Coming from there: it probably depends on the nature of that service. If you only can "serve" customers - then you could omit the customer part - because that doesn't add (much) meaningful information. But what if you later want to serve other kinds of clients?
In other words: we can't tell you what is right for your application - because that depends on the requirements / goals of your environment.
And worth noting: do not only consider todays requirements. Step back and consider those "future grow paths" that seem most likely. And then make sure that the API you are defining today will work nicely with those future extensions that are most likely to happen.
Instead of /service/customers/555/orders/111
Can / should I expose: /service/555/111 ?
The question is broad but as you use REST paths to define nested information, that has to be as much explicit as required.
If providing long paths in the URL is a problem for you, as alternative provide the contextual information in the body of the request.
I think that the short way /service/555/111 lacks consistency.
Suppose that /service/555/111 correspond to invoke the service for the customer 555 and the order 111.
You know that. But the client of the API doesn't know necessarily what the paths meaning are.
Besides, suppose now that you wish invoke the invoke the same service for the customer 555 but for the year 2018. How do that now ?
Like that :
/service/555/2018 would be error prone as you will have to add a parameter to convey the last path value and service/555/years/2018 will make your API definition inconsistent.
Clarity, simplicity and consistency matters.
According to me usage of noun is not necessary or comes under any standard,but yes it's usage helps your endpoint to be more specific and simple to understand.
So if any nomenclature is making your URL more human readable or easy to understand then that type or URL I usually prefer to create and keep things simple. It also helps your service consumer who understand the functionality of any service partially by name itself.
Please follow https://restfulapi.net/resource-naming/ for the best practices.
For a restfull service, does the noun can be omitted and discarded?
Yes. REST doesn't care what spelling you use for your resource identifiers.
URL shorteners work just fine.
Choices of spelling are dictated by local convention, they are much like variables in that sense.
Ideally, the spellings are independent of the underlying domain and data models, so that you can change the models without changing the api. Jim Webber expressed the idea this way
The web is not your domain, it's a document management system. All the HTTP verbs apply to the document management domain. URIs do NOT map onto domain objects - that violates encapsulation. Work (ex: issuing commands to the domain model) is a side effect of managing resources. In other words, the resources are part of the anti-corruption layer. You should expect to have many many more resources in your integration domain than you do business objects in your business domain.
Resources adapt your domain model for the web
That said, if you are expecting clients to discover URIs in your documentation (rather than by reading them out of well specified hypermedia responses), then its going to be a good idea to use URI spellings that follow a simple conceptual model.

how to consume a Restful Web Service (Restful API) in Java

I just want to know the high level steps of the process. Here's my thought on the process:
Assumption: the API returns JSON format
Check the API document to see the structure of the returned JSON
Create a corresponding Java class (ex: Employee)
Make Http call to the endpoint to get the JSON response
Using some JSON library (such as GSON, Jackson) to unmarshall the JSON string to Employee object.
Manipulate the Employee object
However, what if the API returned JSON is changed? it's really tedious task to exam the JSON string every now and then to adjust the corresponding Java class.
Can anyone help me out with this understanding. Thanks
You describe how to consume a json over http API, which is fine since most of the APIs out there are just that. If you are interested in consuming Restful HTTP resources however, one way would be:
Check the API documentation, aka. the media-types that your client will need to support in order to communicate with its resources. Some RESTafarians argue that all media-types should be standardized, so all clients could potentially support them, but I think that goes a bit far.
Watch out for link representations, and processing logic. media-types do not only describe the format of the data, but also how to process them. How to display it if its an image, how to run code that might be part of the message, how to layout onto the screen, how to use embedded controls like forms, etc.
Create corresponding Java classes. If the resources "only" describe data (which they usually do in API context), then simple Java classes will do, otherwise more might be needed. For example: can the representation contain JavaScript to run on the client? You need to embed a JavaScript engine, and prepare your class to do just that.
Make call to a bookmarked URI if you have it. There should be no hardcoded SOAP-like "endpoint" you call. You start with bookmarks and work your way to the state your client need to be in.
Usually your first call goes to the "start" resource. This is the only bookmark you have in the beginning. You specify the media-types you support for this resource in the Accept header.
You then check whether the returned Content-Type matches one of your accepted media-types (remember, the server is free to ignore your preferences), and then you process the returned representation according to its rules.
For example you want to get all the accounts for customer 123456 for which you don't yet have a bookmark to. You might first GET the start resource for account management. The processing logic there might describe a link to go to for account listings. You follow the link. The representation there might give you a "form" in which you have to fill out the customer number and POST. Finally, you get your representation of the account list. You may at this point bookmark the page, so you don't have to go through the whole chain the next time.
Process representation. This might involve displaying, running, or just handing over the data to some other class.
Sorry for the long post, slow day at work :) Just for completeness, some other points the client needs to know about: caching, handling bookmarks (reacting to 3xx codes), following links in representations.
Versioning is another topic you mention. This is a whole discussion onto itself, but in short: some people (myself included) advocate versioning the media-type. Non-backwards compatible changes simply change the media type's name (for example from application/vnd.company.customer-v1+json, to application/vnd.company.customer-v2+json), and then everything (bookmarks for example) continues to work because of content negotiation.
There are many ways to consume RESTful APIs.
Typically, you need to know what version of the API you are going to use. When the API changes (i.e. a different version is exposed) you need to decide if the new functionality is worth migrating your application(s) to the latest and greatest or not...
In my experience, migrating to a new API always requires some effort and it really depends on the value of doing so (vs. not doing it) and/or whether the old API is going to be deprecated and/or not supported by the publisher.

How to determine JAX-RS resource paths programatically?

Suppose I have a set of JAX-RS locators and sublocators, like the following:
#Path("/users")
public class UserListResource {
#Path("/{id}")
public UserResource getCustomer(#PathParam("id") int id) {
// Find and return user object
}
}
public class UserResource {
#GET
public String get() {...}
}
For example, a UserResource object with the ID 5 would have the path "/users/5". In my system, I have several different resources.
Now the question is: How can the server figure out the path of a given resource? Can I do this programmatically via some JAX-RS API or do I have to implement code that uses reflection? (I know how to do the latter, but would prefer the other approach.)
At the point when I need to know the path, I do not have a request object at all. For example, I have a timer which does some background processing, then changes some entities in the domain model, then informs all clients about the changed entities (including their paths).
I know that within the scope of a request, I can inject a UriInfo object that provides this, but I need to know the path in advance (to inform clients of a change that did not necessarily happen through the JAX-RS resource).
I don't want to repeat the path information in another place, and I also don't want to have a set of path fragment constants for each resource type (in this case "/users" and "/{id}").
As I read your question, you need to build a URI knowing only the resource class and the id parameter.
It can be done using the UriBuilder class as in:
UriBuilder builder=UriBuilder.fromResource(UserListResource.class);
URI uri=builder.path(UserListResource.class,"getCustomer").build(5);
It uses reflection under the hood, so it is not so easy to refactor, but it is all it is available at the moment.
Overall, be aware that something sounds rather strange with the architecture of your application. It's hard to put a finger on, but the pattern of questions you are asking is raising a number of red flags about how you're going about this. Be aware that if you are seeking to create a RESTful API to your application that you may need to stop, take a few steps back, and rethink what you are trying to do.
To your explicit questions…
Now the question is: How can the server figure out the path of a given resource? Can I do this programmatically via some JAX-RS API or do I have to implement code that uses reflection? (I know how to do the latter, but would prefer the other approach.)
The server knows the path, as that's always supplied by the user and is used to navigate through the collection of resource classes that make up your application. If you need a UriInfo instance for a particular call, you should inject it as part of that specific call:
#GET
public String get(#Context UriInfo info) {...}
Any information required from the outer context (e.g., what the resource's ID is) is best passed in during construction. You can reparse it out of the URL (obtainable from the UriInfo) again, but that's probably the wrong approach.
Otherwise, if you're doing something much more complex then you need to be more specific in your question.
At the point when I need to know the path, I do not have a request object at all. For example, I have a timer which does some background processing, then changes some entities in the domain model, then informs all clients about the changed entities (including their paths).
I know that within the scope of a request, I can inject a UriInfo object that provides this, but I need to know the path in advance (to inform clients of a change that did not necessarily happen through the JAX-RS resource).
How are you going to have the clients be informed? There's normally no mechanism to push messages from the server to the clients, and clients are typically firewalled so that they can't directly host a service.
Theoretically, you could associate (explicitly, by URL) each resource with its own RSS feed to which a client could listen to if they chose. You wouldn't be able to force clients to listen, but you could give them the option to do so. If you go this route, you don't need to know the UriInfo “ahead of time” as the location information will be present at key times (i.e., at resource creation) and afterwards you're just referring to something that you have control over.
But that's just one way to do it and it adds a lot of complexity; you'd only do it if it was critical to your application. It's often simpler to just have clients poll from time to time. (Note that some sorts of modifications are inherently very destructive; particularly altering the ID or deleting the resource. Don't expect things to cope smoothly with those.)
I don't want to repeat the path information in another place, and I also don't want to have a set of path fragment constants for each resource type (in this case "/users" and "/{id}").
Tough. Repeating information in multiple places, provided you draw it consistently from a single source, is a common practice. There's nothing actually wrong with it.
As I understand your question, you want to know the path as the request is coming in but before it hits your resource; are you open to using Servlet Filters?
JAX-RS specific filters are only supported in 2.0
For the record: after I had posted the question, I thought about our architecture a bit more and came to the conclusion that sending URLS is not as useful as I thought. The application has to know some details about the application structure anyway:
Continuing the example above: even if the client did not know the URL pattern for individual users, it must assume that there is a list of users and know its URL; it also has hard-coded knowledge what dialog to display for editing a user etc.
So all in all, attempting to tell the client (most) URLs it needs is not worth the effort. Instead, we decided to go with a custom API definition file which includes data about the resource contents and their URL scheme. This file is used to generate the following:
the server-side resource classes with the correct JAX-RS annotations
a URL scheme specification document for other developers to code against
classes for our own client (including the URL know how, e.g. user with ID 5 has the URL ...), so we don't have to worry about inconsistencies between our client and server.
This approach has the following advantages:
The need for the server to figure out the URLs from the annotations vanishes, as the client can now do that on its own once it receives a notification that includes the object ID.
We don't have to worry about inconsistencies between our client and the server, as all information is drawn from a single source.
We have one source for the API definition under version control which can be used to verify backwards compatibility with older releases.
Note:
I would probably not claim that the resulting API stays "faithful" to the idea of RESTful webservices, but it works for us and the elements that it borrows from "actual" REST architectural style should make the API clearer and easier to learn than a traditional contract-first webservice.

some clarifications regarding REST PUT verb and other none CRUD based actions

I have read this GREAT answer regarding REST. I have few questions regarding it:
According to the answer and what i read, new resource creation needs happen using the PUT verb but in most cases when you create a resource you need to provide parameters and sometimes binary data.
what is the way to do it with PUT? isn't it more natural to do it with multipart POST?
Can someone direct me to an example for use of PUT to send both binaries and String, preferably using the httpClient library.
What verb to use if i want something that is beyond the basic CRUD actions? like generate a report regarding one of the resources.
Thanks
You are confusing the HTTP Verb with the actual payload.
Nothing prevents you from using a multipart payload for PUT.
POST can be used to create new resources, but you are usually POSTing to a different URL.
As a side-effect, a new resource might get created and returned in the Location header.
PUT is used if you already have the URL to a resource.
REST != CRUD.
A restful architecture forces you to think in resources.
So 'report' might be a good candidate for a resource.
You could POST your report parameters to a resource like /..../reports (for example) and create a new report resource that way. Put the URL for the report in said Location header and use a GET to actually get the report data (or return the report data right away)

Categories