How to create a java client for a Spring service? - java

I have a service definition using Spring annotations. Example (source):
#RequestMapping(value = "/ex/foos/{id}", method = GET)
#ResponseBody
public String getFoosBySimplePathWithPathVariable(
#PathVariable("id") long id) {
return "Get a specific Foo with id=" + id;
}
The question is whether spring (or another library) can auto-create a remote implementation (client) of the same API without the need to manually type paths, method type, param names, etc. (like needed when using RestTemplate)?
Example of an such a client usage:
FooClient fooClient = new FooClient("http://localhost:8080");
String foo = fooClient.getFoosBySimplePathWithPathVariable(3l);
How can I get to such a client "generated" implementation"?

You are probably looking for Feign Client. It does everything you need: calling one service via HTTP is similar to calling method of Java interface. But to make it work you need Spring Cloud, standard Spring framework doesn't have this feature yet.

You can generate it using Swagger Editor. You shoud just define the path of the resources and then it'll generate for you the client for almost any language of your choice

Related

Is there a way to define queryparams for all endpoints in javax.ws.rs?

I am trying to document an already existing application using javax.ws.rs annotations to define what headers (#HeaderParam) and parameters (#QueryParam) a specific endpoint needs. This information would them be used to generate a swagger page for the application.
public Response SampleFunction(#RequestBody(...),
#QueryParam(...),
#HeaderParam(...),
#HeaderParam(...),
#HeaderParam(...),
etc etc etc){
return doStuff()
}
I have identified a set of "#HeaderParam" which are required for all endpoints.
I need to know if there is any way for me to define the #HeaderParam only once and use that definition for all endpoints and, since this is an already existing application, I need to do this change without any major code refactorization.
We believe to have found a solution for this matter.
By declaring the #HeaderParam globally they appear for all endpoints without having to repeat the declaration for each endpoint.
Something like this:
#Path("/")
public class myClass{
#HeaderParam("Parameter_one")
#Parameter(example = "example_one)
Type parameter_one
#HeaderParam("Parameter_two")
#Parameter(example = "example_two)
Type parameter_two
public Response SampleFunction(#RequestBody(...),
etc etc etc){
return doStuff()
}
}
In this particular case, Parameter_one and Parameter_two will become available on the Swagger page for all endpoints.

How to write a Spring Cloud Contract contract for endpoint that uses #ModelAttribute parameter?

This is the endpoint I'm trying to write a SCC contract for. It consumes form data as a DTO and processes it.
PostMapping(value = "/bar/process", consumes = MULTIPART_FORM_DATA_VALUE)
public List<Foo> processBar(
#ModelAttribute("data") BarDto barDto) {
return barService.processBar(barDto);
}
I cannot figure out how to write a groovy contract for this endpoint. I know how to write contract tests for controllers that use multipart form data using #RequestPart annotation, but here - I'm lost.
Can you even use CC with Spring MVC elements?
I'm using SCC version 2.2.7.

How to return a subset of object properties from a Spring Boot restful GET call?

Newbie question...
I'm building my first Spring Boot restful service and want to support a GET call that returns a collection of entities. like:
/api/customers/
However, for certain consumers -like a list page in a web UI - they would only need a subset of the customer entity properties.
I'm thinking that I could add request parameters to my GET call to set the consumers specific field requirements, like
/api/customers/?fields=id,name,address
But what's the best way of implementing this inside the Java restful controller?
Currently in my rest controller the 'GET' is request mapped to a Java method, like
#RequestMapping(value="/", method= RequestMethod.GET)
public Customer[] getList() {
Customer[] anArray = new Customer[];
....
return anArray;
}
Is it possible to somehow intervene with the default Java to Json response body translation so that only the required properties are included?
TIA
Adding fields parameter is a good idea, best practice according to http://www.vinaysahni.com/best-practices-for-a-pragmatic-restful-api#limiting-fields
How to leave fields out?
1) Set them to null, possibly in a dedicated output class annotated with #JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL)
Or
2) Use SimpleBeanPropertyFilter See a good step by step tutorial here 5. Ignore Fields Using Filters

Calling Spring Rest service from c++ or Ruby

I am learning Spring Rest services, I have question regarding Spring rest services
Is it possible to call Spring Rest service from other language like c++ or Ruby, where c++ or Ruby will act as Client and Spring Rest service as service or resource provider.
If it's possible can some one explain simple, detailed manner with example.
The reason of asking the question, if we develop a web service using Jax-ws, the interoperability will happen across the technologies like calling Java based web service calling from C++ or and vice versa, can same thing happen using Rest service which is developed in Spring Rest or using Jersey api framework.
A REST call is just an http call. The service doesn't care what language the client is coded in - could be a browser, a mobile phone, written in c++, java, c, objective-c, it doesn't matter.
Typically if you have object data to pass from the client to the service, you would encode it in JSON or XML.
Yes, it is possible. The key of course is Serializing/Deserializing Data. As long as your Rest service accepts serialized data as input, and returns serialized data as output.
For Example, lets say you have an endpoint http://www.example.com/public-api/foo, with acceptable method GET (it provides data).
In Spring, you have a resource named Foo.java, that takes the following form
class Foo implements Serializable {
private static long serialVersionUID = -1L;
private String someProperty;
public Foo() {
...
}
public String getSomeProperty() {
return this.someProperty;
}
public void setSomeProperty(String someProperty) {
this.someProperty = someProperty;
}
}
With the following Controller
#Controller
#RequestMapping(value={"/"})
class FooController {
#RequestMapping(value={"/foo"}, method={RequestMethod.GET})
public HttpEntity<Foo> foo() {
...
Foo foo = new Foo();
...
return new ResponseEntity<ResourceSupport>(foo, HttpStatus.OK);
}
}
When you access this in your browser, it will return the following text
{
"_self": "http://www.example.com/public-api/foo",
"someProperty": ...
}
This output (in JSON), can be parsed in Ruby and C++ (or any language really) quite simply.
Inputting is the same way. Instead of parsing JSON, you would just POST or PUT JSON data that conforms to whatever resource you're trying to input. To POST or PUT a new Foo object, you just POST or PUT JSON data with the appropriate Properties.

How to get the POST/GET params in a java WebMethod?

I have created a java web service with netbeans 7.1 (glassfish3.1).
It is supposed to be visited via clicking a URL (like: http://localhost:8080/ImageService/GetImage?visitDate='2012-01-01') to generate an image for web users. And there are some parameters in the URL that I need to get to use inside the WebMethod.
#WebMethod(operationName = "GetImage")
public void GetImage() {
// Date visitDate = GET["visitDate"];
...
}
Or, how can I make the java web service invoked via http get method?
PS: In .net, this config will enable the feature - calling a web service via URL. I'm asking for a java version.
<webServices>
<protocols>
<add name="HttpPost"/>
<add name="HttpGet"/>
</protocols>
</webServices>
Is this doable? How can I get that work?
Thanks!
Finally, I have given up this, turn to use jsp to do that. But still hoping someone can tell me - if web-service way is possible or not.
Thanks!
The #WebParam annotation is defined by the javax.jws.WebParam interface. It is placed on the parameters of the methods defined in the SEI. The #WebParam annotation allows you to specify the direction of the parameter, if the parameter will be placed in the SOAP header, and other properties of the generated wsdl:part.
#WebMethod(operationName = "GetImage")
public void GetImage(#WebParam(name = "visitDate")String visitDate) {
//...
}

Categories

Resources