What is the proper way to add a map in a REST request - rest

I'm using Google Endpoint and for one of my entities I want to create a POST request that adds a map of properties. What is the right way to do it?
I know Google Endpoint can receive a Collection as a parameter, but I want to add a map (unknown key values).
Should I pass a JSON as a parameter or just add the JSON in the body of the request and extract it from the HttpServletRequest object?

I would avoid passing it as a parameter. You can send it in the body of the request and then use json library to get a python object.
https://docs.python.org/3/library/json.html

Every JSON object is a map, so it looks like the most obvious choice. GSON makes it easy, but you can use other parsers too.
Type type = new TypeToken<Map<String, String>>(){}.getType();
Map<String, String> myMap = gson.fromJson("{'k1':'apple','k2':'orange'}", type);

Related

Access nested body property from HTTP resolver(AppSync)

I'm new to AWS AppSync and I am trying to access certain body property(from HTTP response) in my resolver's response mapping template.
For example: I am able to present the response as is via $util.toJson($ctx.result.body), but when I try to get some of the nested body properties it fails.
For example, imagine the body looks like this:
{
about:{
"firstName":"Chuck",
"lastName":"Norris"
}
}
and $util.toJson($ctx.result.body.about) returns null. Any thoughts?
I found a way extract the parsed body in the following way:
#set ($parsed_body = $util.parseJson($ctx.result.body))
And then I am able to access the properties via dot notation:
parsed_body.about.firstName
The part I was missing is $util.parseJson(<json-string>)
It seems that the body is a JSON string.

What is the best solution to pass two different parameters to a REST API?

I have a doubt about what could be the best way to define a REST URI for an API.
I have an API that provide the details of a commodity.
So I know that I can do a GET request like this:
http://XXX.YYY.ZZZ.TTT:8280/commodity_details/1
where commodity_details is what I want to obtain (a commodity details) and 1 is the ID of a specific commodity. This should be a proper REST URI.
Ok, I know that I can also pass the ID parameter into a JSON document doint a POST request like this:
http://XXX.YYY.ZZZ.TTT:8280/commodity_details/
and attacching a JSON payload like this to my POST request:
{
"commodity_id": 1
}
I think that if I have the single commodity_id parameter maybe is better the first version (putting the required ID into the URI), is it?
But what happens if I need a second language_id parameter? (my API should receive also this language_id parameters so it can provide an internazionalized output in the proper language.
So in this case I need to pass 2 parameters (commodity_id and language_id).
In this case is better use a POST request with a JSON payload that contains both the parameters? Something like this:
{
"commodity_id": 1,
"language_id": 2
}
Or what could be a good URI template for this scenario?
For passing just 2 parameters you can go with first approach(query string parameter) which is simpler to use
[HttpGet("{commodity_id}/{language_id}")]
public string GetCommodityDetails(string commodity_id, string language_id)
{
string commodityDetails=string.empty;
//your implementation
return commodityDetails;
}

How to pass any number of headers to Feign client without knowing all the names?

I've a use case where I need to pass all headers that start with a certain prefix to the feign client. I don't know the number or exact names of these headers. There doesn't seem to be a way to to do this easily as the Feign client expects all headers to be specified using #RequestHeader("name"). It doesn't seem to support something like #RequestHeader HttpHeaders, which would be very useful.
Any suggestions?
As of this writing, Feign doesn't support dynamic headers or query parameters using a Map. The Spring Cloud Feign client relies on the Spring annotations instead of Feign annotations, and the implementations of AnnotatedParameterProcessor have a bug such that they don't do what the documentation states they should be doing.
RequestHeader doc:
If the method parameter is Map, MultiValueMap, or HttpHeaders then the
map is populated with all header names and values.
RequestParam doc:
If the method parameter is Map or MultiValueMap and a parameter name
is not specified, then the map parameter is populated with all request
parameter names and values.
I submitted a pull request that will fix this. Until then, I'm using an extension of SpringMvcContract that uses my own AnnotatedParameterProcessor implementations. I set the custom SpringMvcContract using a Feign.Builder as follows:
#Autowired
FormattingConversionService feignConversionService;
#Bean
#Scope(SCOPE_PROTOTYPE)
public Feign.Builder feignBuilder() {
return HystrixFeign.builder()
.contract(feignContract());
}
#Bean
public Contract feignContract() {
return new EnhancedSpringMvcContract(feignConversionService);
}
From the documentation, you should be able to specify a header map for dynamic headers.
In cases where both the header field keys and values are dynamic and the range of possible keys cannot be known ahead of time and may vary between different method calls in the same api/client (e.g. custom metadata header fields such as "x-amz-meta-" or "x-goog-meta-"), a Map parameter can be annotated with HeaderMap to construct a query that uses the contents of the map as its header parameters.
#RequestLine("POST /")
void post(#HeaderMap Map<String, Object> headerMap);

How to add arguments without key, to add only value to the body of ConnectionRequest

I want to add a Json object to ConnectionRequest as value without key. I know that if use standard addArgument(key,value) -
addArgument("json","{JsonObject}")
in the body of request will be
json={JsonObject}
But I need to add only JsonObject without key and "=" symbol.
{JsonObject}
Is there any standard solution?
One more question Is there any class in Lwuit to create JsonObject similar to json.org.me
Thanks
Sure, just override
protected void buildRequestBody(OutputStream os)
And write whatever you want into the output stream. Don't use the arguments this will replace them anyway.

http delete with REST

I am currently using Jersey Framework (JAX-RS implementation) for building RESTful Web Services. The Resource classes in the project have implemented the standard HTTP operations - GET,POST & DELETE. I am trying to figure out how to send request parameters from client to these methods.
For GET it would be in the query string(extract using #QueryParam) and POST would be name/value pair list (extract using #FormParam) sent in with the request body. I tested them using HTTPClient and worked fine. For DELETE operation, I am not finding any conclusive answers on the parameter type/format. Does DELETE operation receive parameters in the query string(extract using #QueryParam) or in the body(extract using #FormParam)?
In most DELETE examples on the web, I observe the use of #PathParam annotation for parameter extraction(this would be from the query string again).
Is this the correct way of passing parameters to the DELETE method? I just want to be careful here so that I am not violating any REST principles.
Yes, its up to you, but as I get REST ideology, DELETE URL should delete something that is returned by a GET URL request. For example, if
GET http://server/app/item/45678
returns item with id 45678,
DELETE http://server/app/item/45678
should delete it.
Thus, I think it is better to use PathParam than QueryParam, when QueryParam can be used to control some aspects of work.
DELETE http://server/app/item/45678?wipeData=true
The DELETE method should use the URL to identify the resource to delete. This means you can use either path parameters or query parameters.
Beyond that, there is no right and wrong way to construct an URL as far as REST is concerned.
You can use like this
URL is http://yourapp/person/personid
#DELETE
#Path("/person/{id}")
#Produces(MediaType.APPLICATION_JSON)
public Response deletePerson(#PathParam("id") String id){
Result result = new Result();
try{
persenService.deletePerson(id);
result.setResponce("success");
}
catch (Exception e){
result.setResponce("fail");
e.printStackTrace();
}
return Response.status(200).entity(result).build();
}
#QueryParam would be the correct way. #PathParam is only for things before any url parameters (stuff after the '?'). And #FormParam is only for submitted web forms that have the form content type.