How to make a request parameter optional in Spring REST Docs - spring-restdocs

I know fieldWithPath() has optional() but didn't find how to make parameterWithName() optional.

In Spring REST Docs 1.1 you can mark request and path parameters as optional. If you want that information to also appear in the generated table you can use a custom snippet that adds the optional column (once this bug has been fixed).
In Spring REST Docs 1.0 you can't mark a request parameter as optional via a first-class API. I would recommend using a combination of a custom attribute on the parameter descriptor and, if necessary, setting the ignored flag on the descriptor to allow the test to pass in the parameter's absence.

Related

Macros in Datafusion using Argument setter

Using Argument setter by supplying the parameter value I want to make the Datafusion pipeline as resuable. As said by many other answer's have tried implementing using the cloud reusable pipeline example given in Google guide.I was not able to pass the parameter Json file.So how to create the API to that parameter Json file stored in Google storage.Please explain the values to be passed to Argument setter like URL,Request response etc., If any one of you had implemented in your projects.
Thank you.
ArgumentSetter plugin reads from a HTTP endpoint and it must be publicly accessible as is depicted within the GCP documentation. Currently, there is not a way to read from a non-public file stored in GCS. This behavior has been reported in order to be improved to CDAP through this ticket.
Can you please provide what you've tried so far and where you're stuck?
The URL field in argument setter would contain the API endpoint you're making a call to. Make sure you include any headers your call would need like Authorization, Accept etc.
If you're having issues with argument setter a good check is to use Curl or any other tool to make sure you're able to talk to the endpoint you're trying to use.
Here's some documentation about Argument setter: https://github.com/data-integrations/argument-setter
Define a JSON file with appropriate name/value pairs. Upload it in a GCS bucket - make it public by changing permissions (add "allUsers" in permissions list). When you save it, the file will say "Public to Internet"
Copy the https path to the file and use it in Arguments Setter. If you're able to access this path from curl/ your browser, Argument Setter will be able to do too..
There are other problems I've encountered while using Argument Setter though - the pipe doesn't supersede runtime arguments over default values provided in the URL many a times, specially when the pipe is duplicated.
To make file public
You have to make your bucket public, currently there is no other way.
gsutil iam ch allUsers:objectViewer gs://BUCKET_NAME

Creating two different rest api with optional values

I am just new to rest api and need to create two api. both of them use post.
1) First one takes 2 parameters inside of the body
url is : /myapp/resources
2) Second one is doing the same function as the first one does but it needs 2 optional parameter. I thought using path or request param but as the parameters are optional it will be confusing when there is no paramaters. So there will be conflict with the first api.
/myapp/resources?param1=xx&param2=xx ==> what if there is no parameter
/myapp/resources/param1/{xxx}/param2/{yyy} ==> so still what if there is no param:
So what is the best way to define second api without causing a conflict with the first api when optional parameters are not passed.
I would suggest going with the first approach (query params) so:
/myapp/resources?param1=xx&param2=xx
The reason being - in this case you can define or extend the logic of just one endpoint, the /myapp/resources, that is going to verify if parameters exist and react accordingly.
With the second approach (path params), you would have to most likely define two (or more) separate endpoints (like /myapp/resources/, /myapp/resources/param1/{param1} and /myapp/resources/param1/{param1}/param2/{param2}

Is it possible to make the same field compulsory for POST and optional for PUT requests?

Is it possible to make the same field compulsory for POST and optional for PUT requests for REST API? Or it depends on teqnology used to implement this request?
For example, there is a POST request to create Car objects and this object has a field model_id which is actually chosen from a dictionary of models. And the POST request requires model_id because the car must have model_id defined.
And I want to have a PUT method which changes some field e.g. serial_num, manufacture_date, color etc. even model_id. But I want this PUT method to change model_id as optional parameter, e.g. I just want to change color and it is Ok.
So is this possible in REST? Does some technologies that implement these request could not allow me to make different set of optional/compulsory params for POST ant PUT?
Well, you can do whatever you want here. Nobody will kill you if you check fields in the request body and return an error if model_id is specified (or not).
Some guys use POST method to update entities in API.
If you want to be closer to standards better use PATCH for partial updates.
You can find a lot of interesting info here:
https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods
Use of PUT vs PATCH methods in REST API real life scenarios
https://www.rfc-editor.org/rfc/rfc7231#section-4.3.4
https://www.rfc-editor.org/rfc/rfc5789
One important thing from 4. source:
The PUT method is already defined to overwrite a resource with a
complete new body, and cannot be reused to do partial changes.
And another one sentence from 3. source:
Generally speaking, all implementation details behind the resource interface are intentionally hidden by the server.

JAX-RS and unknown query parameters

I have a Java client that calls a RESTEasy (JAX-RS) Java server. It is possible that some of my users may have a newer version of the client than the server.
That client may call a resource on the server that contains query parameters that the server does not know about. Is it possible to detect this on the server side and return an error?
I understand that if the client calls a URL that has not been implemented yet on the server, the client will get a 404 error, but what happens if the client passes in a query parameter that is not implemented (e.g.: ?sort_by=last_name)?
Is it possible to detect this on the server side and return an error?
Yes, you can do it. I think the easiest way is to use #Context UriInfo. You can obtain all query parameters by calling getQueryParameters() method. So you know if there are any unknown parameters and you can return error.
but what happens if the client passes in a query parameter that is not implemented
If you implement no special support of handling "unknown" parameters, the resource will be called and the parameter will be silently ignored.
Personally I think that it's better to ignore the unknown parameters. If you just ignore them, it may help to make the API backward compatible.
You should definitely check out the JAX-RS filters (org.apache.cxf.jaxrs.ext.RequestHandler) to intercept, validate, manipulate request, e.g. for security or validatng query parameters.
If you declared all your parameters using annotations you can parse the web.xml file for the resource class names (see possible regex below) and use the full qualified class names to access the declared annotations for methods (like javax.ws.rs.GET) and method parameters (like javax.ws.rs.QueryParam) to scan all available web service resources - this way you don't have to manually add all resource classes to your filter.
Store this information in static variables so you just have to parse this stuff the first time you hit your filter.
In your filter you can access the org.apache.cxf.message.Message for the incoming request. The query string is easy to access - if you also want to validate form parameters and multipart names, you have to reas the message content and write it back to the message (this gets a bit nasty since you have to deal with multipart boundaries etc).
To 'index' the resources I just take the HTTP method and append the path (which is then used as key to access the declared parameters.
You can use the ServletContext to read the web.xml file. For extracting the resource classes this regex might be helpful
String webxml = readInputStreamAsString(context.getResourceAsStream("WEB-INF/web.xml"));
Pattern serviceClassesPattern = Pattern.compile("<param-name>jaxrs.serviceClasses</param-name>.*?<param-value>(.*?)</param-value>", Pattern.DOTALL | Pattern.MULTILINE);

Issue: Action redirect do not include parameter as complex objects in Struts2?

I have tried an example in which i have inserted a user using insert method of UserAction class.
On insert I have redirected the success to loadAdd method of UserAction.
During redirect I have passed the parameter as
${user}
In struts 2.0.14 this gives an ognl exception.
whereas when I pass
${user.id}
it works.
My observation says this is a bug in struts or ognl that it does parse composite objects while it parses simple data types.
Any work-around please suggest.
Or
Is there any way by which I can forward the complete action context or value stack in the redirected action
It's not a bug.
Struts2 uses a type conversion system to convert between Strings (native HTTP) and other objects. It has default type converters for all of the standard primitives, boxed primitives, collections, maps, etc. If you want to allow Struts2 to automatically convert between a string and your User class, you need to create a type converter for it. Otherwise, you can use ${user.id}, which is a primitive or boxed primitive.
http://struts.apache.org/2.2.3/docs/type-conversion.html
Also, the ValueStack is per-request, so when you redirect and create a new request, the previous requests ValueStack is no longer available.