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

Support for search operations #16

Closed
amaxilat opened this issue Apr 13, 2018 · 7 comments
Closed

Support for search operations #16

amaxilat opened this issue Apr 13, 2018 · 7 comments

Comments

@amaxilat
Copy link

Hi there,
I have been using the project for creating simple clients for our JSON+HAL REST API but I cannot find how to map the search operations. Is it somewhere and I cannot find it or is it not yet supported?

i.e., for something like this:

curl localhost:8080/v1/items/search {
  "_links" : {
    "findByType" : {
      "href" : "http://localhost:8080/v1/items/search/findByType{?type,page,size,sort}",
      "templated" : true
    },
    "findById" : {
      "href" : "http://localhost:8080/v1/items/search/findById{?Id}",
      "templated" : true
    },
    "self" : {
      "href" : "http://localhost:8080/v1/items/search"
    }
  }
}
@hdpe
Copy link
Owner

hdpe commented Apr 13, 2018

Hi, unfortunately I think it's safe to say this isn't supported out of the box. The _links are currently assumed by Bowman to be linked resources, with an underlying Bowman-annotated class. There is no mechanism at present for resolving this linked resource's templated link and 'invoking' it.

Thanks for raising this. I will have a think about what supporting this would mean and what it might look like. I'd be interested to see any suggestions you might have for what the client API might be, how you'd map the resources etc.

@hdpe
Copy link
Owner

hdpe commented Apr 22, 2018

So I've had a think, and I reckon this is probably the path of least resistance. We should:

  • Introduce a new method Client.get() for retrieving a mapped single-valued resource (currently, we assume it is a collection-valued resource that is mapped, and the get method takes the URI id of the specific item required as a parameter)
  • Support proxying of methods with any name if they are annotated with @LinkedResource (currently, only get*, is*, set* are supported)
  • Support proxying of methods with parameters, and map these parameters to those given in the templated link, e.g. build link from the template http://localhost:8080/v1/items/search/findByType{?type,page,size,sort} and the four provided method arguments (currently, all proxied 'lookup' methods are assumed to have no params)
  • Support mapping of interface types as linked resources - we don't want to use JavaBean-style classes to map the remote resources in this case, as the client model can't act as a data container and there is no appropriate default implementation for the methods (currently, only class types are supported)

Putting it all together, for the resource http://blah/items/search:

{
    "_links": {
        "findByName": {
            "href": "http://blah/items/search/findByName{?name}",
            "templated": true
        }
    }
}

you could do:

@RemoteResource("/items/search")
interface Search {

    @LinkedResource
    Item findByName(String name);
}

then:

Client<Search> search = factory.create(Search.class);

Item item = search.get().findByName("x");

and it feels like this would probably get you what you want. What do you think? I've got a proof of concept working locally that demonstrates this. If it seems like this is what you're after, I'll get it tidied up and merged in.

Thanks

@hdpe hdpe closed this as completed in 69a6dd7 Apr 30, 2018
@FlorianFusseder
Copy link

Hey,
this seems like a great feature, when do you think it will be released?

Greetings,
Flo

@hdpe
Copy link
Owner

hdpe commented May 14, 2018

@FlorianFusseder - released as 0.4.0.

Thanks

@danapoklepovich
Copy link
Contributor

danapoklepovich commented Jul 3, 2018

Hi @hdpe I've been trying to get searching working to return a collection of myItems rather than just a single myItem like your example above. At the moment the response resources are returning the appropriate rows however I am running into a NPE because the originalMethod param of the below method is being passed in as null as I believe it is because there is no self reference for the collection of myItems. You would have a lot more knowledge than I do about how things are working here, so was wondering if this was something in the pipeline for development or does it not match your use cases? And what would be involved in implementing this particular feature?

private <F> Collection<F> resolveCollectionLinkedResource(URI associationResource, Class<F> linkedEntityType, Object contextEntity, Method originalMethod) throws IllegalAccessException, InvocationTargetException { Resources<Resource<F>> resources = this.restOperations.getResources(associationResource, linkedEntityType); Collection<F> collection = (Collection)originalMethod.invoke(contextEntity); if (collection == null) { collection = this.propertyValueFactory.createCollection(originalMethod.getReturnType()); } else { collection.clear(); }
Iterator var7 = resources.iterator();

    while(var7.hasNext()) {
        Resource<F> fResource = (Resource)var7.next();
        collection.add(this.proxyFactory.create(fResource, this.restOperations));
    }

    return collection;
}

`

@hdpe
Copy link
Owner

hdpe commented Jul 3, 2018

@danapoklepovich sorry about this, and thanks for raising. Your analysis of what's happening here seems completely correct to me. I'll raise this as a new issue.

@danapoklepovich
Copy link
Contributor

@hdpe legend! thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants