Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Default Overview of a JAX-RS bean #657

Closed
amihaiemil opened this issue Sep 10, 2018 · 20 comments
Closed

Default Overview of a JAX-RS bean #657

amihaiemil opened this issue Sep 10, 2018 · 20 comments
Assignees
Labels
api enhancement New feature or request

Comments

@amihaiemil
Copy link

amihaiemil commented Sep 10, 2018

HATEOAS is one of the most important principles of a RESTful API and this includes navigability. I always like to use the following metaphor: when navigating a RESTful API from the browser, the user should get the feeling that they are playing with a poorly loaded website, which only displays the HTML structure and links, without any CSS.

This said, take the below JAX-RS class:

@Path("/teams")
public class Teams {

    @GET
    @Path("/{teamId}")
    public Response team(@PathParam String teamId) {
        //return team by its id
    }

   @GET
   @Path("/{teamId}/projects")
   public Response projects(@PathParam String teamId) {
       //return a team's projects.
   }
}

From my experience, currently, if the user calls example.com/api/teams (not knowhing the exact methods of /teams), they get 404 NOT FOUND. Instead, I think JAX-RS should automatically display a Json/XML/whatever (so Content Negotiation, somehow) containing the links offered by /teams. Something like this:

{
    "Fetch a Team": {
        "Method": "GET",
        "Link": "example.com/api/teams/{teamId}"
    },
   "Fetch a Team's Projects": {
        "Method": "GET",
        "Link": "example.com/api/teams/{teamId}/projects"
    }
}

At the moment, if we want the upper effect to happen, we have to make the Teams bean implement javax.json.JsonObject (or extend an abstract implementation of javax.json.JsonObject) and pass all the information to the super JsonObject in its ctor. It looks like this:

@Path(/teams)
public class Teams extends AbstractJsonObject {
    private static final String TEAM_ID = "/{teamId}";
    private static final String PROJECTS = "/{teamId}/projects";
    
    public Teams() {
        super(TEAM_ID, PROJECTS);
    }
    
    @GET
    @Path("/")
    public Response docs() {
        return Response.ok().entity(this.toString()).build();
    }

    @GET
    @Path(TEAM_ID);
    //...
 
   @GET
   @Path(PROJECTS);
   //...
}

Given this polymorphism is rather simple to implement, I would like to see JAX-RS do it out of the box. What do you think?

I believe this functionality could ultimately replace any automatically-generated documentation such as Swagger.

@mkarg
Copy link
Contributor

mkarg commented Sep 10, 2018

-1

  • What you propose it is just syntactic sugar ontop of something you can already achieve without it, so there is neither a real need for a specification nor a substantial simplification of the achieved task.
  • Your proposal enforces exactly one particular solution, but other programmers might like to have a different solution for the same problem (interface self-description aka resource method discovery), e. g. WADL, or OPTIONS returning Link headers.

@amihaiemil
Copy link
Author

amihaiemil commented Sep 11, 2018

@mkarg

What you propose it is just syntactic sugar ontop of something you can already achieve without it

Well, the fact that it's easy to implement is not an argument. Most developers don't even understand what REST actually is. I suppose you know this famous rant of Mr. Fielding. Also, here are my (more elaborate) thoughts on it.

So, even if it's simple to implement, most don't think about it and JAX-RS should do as much as possible to lead developers on the right path. Not to mention, there are dozens of "rest" frameworks which don't really help developers make a RESTful api, they just help them expose some HTTP endpoints... I don't want JAX-RS to be just a kit for HTTP endpoints, I want it to be as helpful as possible in the "REST" direction. :D

Your proposal enforces exactly one particular solution

This can be discussed and the best solution can be found. I see no problem in having both the GET and the OPTIONS alternative :-?

@mkarg
Copy link
Contributor

mkarg commented Sep 11, 2018

@amihaiemil I well understand your point, but frankly spoken, your arguments still do not convince me. In particular the idea seems to be incomplete. Maybe you like to hack a PoC which demonstrates how OPTIONS and GET alternatives work together, and in particular, how GET (your solution) and GET (any other solution) work together? I mean, this smells like the need for a solution provider in the end.

@mkarg mkarg added enhancement New feature or request api labels Sep 12, 2018
@amihaiemil
Copy link
Author

amihaiemil commented Sep 13, 2018

@mkarg I only mentioned OPTIONS or others because you brought it on the table. :D

I personally think a GET would be enough, since it's the simplest, most intuitive way of seeing the APIs overview. It would be primarily for human usage (let's call it like this): developer reads it from the browser, same as they use Swagger. Then, I think fluent tests and clients would be designed much easier (see my article, linked in the previous comment).

The described polymorphim is just how I'd do it now. If JAX-RS had this, I would expect to have the default path / or /overview in each class (and probably specify ?format=xml or ?format=json to enforce the content-type.

Now, of course, some users may have their own / or /overview paths, so JAX-RS could have the @Overview("/path") annotation (to be used on classes).

So this is just a nice-to-have idea, simple indeed, but which I believe would greatly increase the quality (especially regarding REST paradigm) of apis built with JAX-RS.

May I ask, what is the process exactly? Do people vote on proposed ideas such as this one? Will it be discussed somewhere or simply stay here until some Github users upvote/downvote it? :D

@mkarg
Copy link
Contributor

mkarg commented Sep 13, 2018

@amihaiemil Jersey, just to name one, already provides such a self-description using WADL, but on a different path. So what you propose is incompatible. How to solve this discrepancy? Someone now needs to make WADL go away and implement your counter proposal. Why should he? Who pays for that, and who has the actual benefit? Your solution is just, different, but IMHO not any better than what Jersey already does.

The process at the EF is "code first" and "proven usefulness":

  • You can discuss usefulness on an abstract level here. No voting needed as this is just an open discussion not a PR; nobody will do any work for you until you convince him. ;-)
  • Some vendor has to add this feature and release it. You could do a PR for Jersey for this step and convince the Jersey committers that this is great and needed so they will adopt it into their next release.
  • Wait for several weeks. Feedback has to be provided by users that they love that feature and want all vendors to support it.
  • Discuss the feedback and the resulting changes to your proposal here. Start by posting a collection of the positive feedback so the JAX-RS commiters are convinced this is a good thing.
  • Someone, maybe you, files a PR against the JAX-RS master branch.
  • Committers will vote within two weeks after filing. If there are 2x +1 and 0x -1 then you win. :-)

@amihaiemil
Copy link
Author

@mkarg I see, thanks for the thorough explanation. I'll try to see what the Jersey guys say :)

@arjantijms
Copy link
Contributor

@amihaiemil I'm technically one of the Jersey guys (albeit a rather new one), but I'd personally say that if the proposal to add HATE OS to JAX-RS is accepted, then surely I'd like to look at implementing it in Jersey (according to the JAX-RS API/specs). However, I'd personally don't see any merit in implementing HATEOS specifically for Jersey in a proprietary way.

Of course I'm only one voice and not even the main voice of the Jersey project, so maybe the other committers think differently about this, but this is my opinion.

@mkarg
Copy link
Contributor

mkarg commented Sep 15, 2018

@arjantijms Can we also get an official statement of the Jersey team, e. g. from @jansupol?

@amihaiemil
Copy link
Author

@mkarg I opened an Issue to the Jersey repo, pointing here. I also opened one for RestEasy (they manage tickets in Jira, unfortunately, so no Github reference).

@mkarg
Copy link
Contributor

mkarg commented Sep 19, 2018

@amihaiemil So you now start implementing Jersey / RESTeasy or what is your next step?

@amihaiemil
Copy link
Author

amihaiemil commented Sep 19, 2018

@mkarg Well you said that a vendor should implement it first before it can be made a standard, so I asked Jersey and RestEasy about it, right? To my knowledge, they are the biggest vendors for JAX-RS.

@mkarg
Copy link
Contributor

mkarg commented Sep 19, 2018

@amihaiemil Let's see if a vendor is willing to implement your wish or simply nothing happens, because both are open source projects and you are assumed to provide a PR... ;-)

@amihaiemil
Copy link
Author

@mkarg of course, I could study the projects and maybe provide a PR, but first I want to see if someone supports the idea or not.

@mkarg
Copy link
Contributor

mkarg commented Sep 19, 2018

@amihaiemil Let's see what happens. ;-)

@asoldano
Copy link

asoldano commented Sep 19, 2018

@mkarg I opened an Issue to the Jersey repo, pointing here. I also opened one for RestEasy (they manage tickets in Jira, unfortunately, so no Github reference).

@amihaiemil , how about a link to the jira you created?

@amihaiemil
Copy link
Author

@asoldano Right, here it is: https://issues.jboss.org/browse/RESTEASY-2022

@mkarg
Copy link
Contributor

mkarg commented Oct 21, 2018

@amihaiemil Can you please concicesly report on the progress of this issue? Is this feature already implemented somewhere? Is there already some feedback to share?

@amihaiemil
Copy link
Author

@mkarg As we discussed, I started looking into the Jersey source code (product implementation comes first, then maybe it becomes a standard, that's what I understood). Should I make a PR with the @Overview annotation which I described above?

@mkarg
Copy link
Contributor

mkarg commented Oct 23, 2018

@amihaiemil A PR against JAX-RS makes no sense as long a there is no feedback from users of the existing feature. So unless the feature you are working on got adopted by Jersey and produced a mostly positive user feedback, all you can share in the JAX-RS issue is a link to your Jersey PR.

@amihaiemil
Copy link
Author

@mkarg Closing, as explained here. Thanks!

@mkarg mkarg self-assigned this Dec 16, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
api enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

4 participants