How to pass a map as query parameter - rest

I'm using labstack Echo (v4.1.11) go framework to create a REST API.
How do we/can we pass map query param in the URL? I tried adding the following struct for the request body
PaginationRequest struct {
Page int64 `query:"page"`
Limit int64 `query:"limit"`
Filter map[string]string `query:"filter"`
}
and hoping I could got this url http://host/endpoint?page=1&limit=10&filter[status]=1&filter[user_id]=12 to work (read the filter["status"] and filter["user_id"]
But when I tried binding the incoming request to PaginationRequest it only read the page and limit parameter and filter = nil
I tried debug it into the echo/bind.go the Bind function in reading the QueryParam actually read filter[status] as plain string "filter[status]" as key.
Is there anyway we can pass the map to the url query param? or we really have to be specific in here?

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;
}

Fetching the Odata query parameter in code

I have a rest Get method Ex:-
public IQueryable<Test> GetTest() {
return _service.GetAll();
}
I want to fetch the query parameter in code which was the part of the request url, I cant give OdataQueryOption parameter in the method like GetTest(OdataQueryOption
op).
Please suggest a solution
Assuming you're implementing an ODataController you should be able to access this.Request.RequestUri.Query. If you want the name/value pairs you should use System.Web.HttpUtility.ParseQueryString to get a NameValueCollection.

How to access invoke response object variable in following steps of assembly

the assembly of my API Connect API contains two invokes. The first is calling an internal routing API to get some routing information. The response of this routing API should not be passed to the second invoke.
If I do not configure a 'response object variable' in the invoke of the routing API, the original request body is overwritten and the second API gets the result from the routing API as request body. And if I specify a 'response object variable' in the routing invoke, I can not access the content (json) of this variable in the following steps.
How can I solve this issue?
Thx 4 help.
Rather than relying on reading the request object, you can read from your configured 'response object variable' later on in the flow. For instance, if your first invoke has a response object variable set to 'resp1', you can access the JSON payload using '$(resp1.body)' later on in the flow. Using this technique will allow you to store the response of each invoke in a separate object, avoiding the overwriting issue. These response object variables can be read just like any other context variable in the flow.
For more info, check out these links in the Knowledge Center:
Invoke Policy: https://www.ibm.com/support/knowledgecenter/en/SSMNED_5.0.0/com.ibm.apic.toolkit.doc/rapim_ref_ootb_policyinvoke.html
Context Variables:
https://www.ibm.com/support/knowledgecenter/SSMNED_5.0.0/com.ibm.apic.toolkit.doc/capim_context_references.html
I don't understand this part:
[...] "And if I specify a 'response object variable' in the routing
invoke, I can not access the content (json) of this variable in the
following steps." [...]
Why can't you access the content of this variable in the following steps?
Save copy of the request...
... that you received. What I'd do is always save a copy of the data received in the invoke to a processed variable instead of the (raw) original request.
In your GatewayScript try something like this:
let objRequest = apim.getvariable("request");
let body = null;
Here I recommend you to change the body (if json) to a standard js object
if(objRequest && objRequest.hasOwnProperty("body")){
try{
body = JSON.parse(objRequest.body);
}catch(e){
body = objRequest.body;
}
}
Remember to stringify the complete object before saving it as global variable. Is the only way to store it (because you can only store a string value in this kind of variables)
apim.setvariable("objRequest", JSON.stringify(objRequest));
Retrieve copy of the request...
...that you have saved in global variables you can get it from any other GatewayScript that you want this way:
let objRequest = JSON.parse(apim.getvariable("objRequest"));
Be careful not to assign an existent name to the apim.setvariable(name, value) because if you use "request" as name instead of "objRequest" (or other), you'll be replacing the original request element, and we don't want that to happen.
If you need to set or retrieve the status.code...
...you can do it with:
let statusCode = objRequest.body.status.code;

How can I define an Angular resource that doesn't use query parameters for REST GET?

Currently I have a resource defined in Angular like this:
Users: $resource(APIBASEROUTE +'/users/:_id', {_id: '#_id'})
When I call for a user with this code:
$scope.user = ayApi.Users.get({id:$routeParams.userId});
The request is sent as a query parameter like this:
http://localhost:3000/api/v1/users?id=526eff826a6100fb22000000
However it needs to hit the REST server like this:
http://localhost:3000/api/v1/users/526eff826a6100fb22000000
How do I make Angular do it this way?
I guess that the problem is in incosistency of the parameters names.
in definition you have: {_id:'#_id'}), it should be the {id...
Or in your call it should be with underscore
$scope.user = ayApi.Users.get({_id:$routeParams.userId});
Any other parameter (not mapped in the resource definition) is treated as a query string param. That's why angular decided to append your id as a query string part. It is not _id