I'm writing some functional tests for a Grails controller, and I feel it's getting messy when testing the query parameters.
I know that I can do this, but it just seems clunky.
Map getParms = [id:1, x:foo, y:bar, z:baz]
RestResponse response = builder.get("http://example.com/api/{id}?x={x}&y={y}&z={z}") {
urlVariables getParams
}
Ideally I'd like to:
Fill the base URL (i.e. the Id) using the urlVariables argument above
Pass another map of query params that appends each as a key value pair
Something like:
Map queryParms = [x:foo, y:bar, z:baz]
RestResponse response = builder.get("http://example.com/api/{id}") {
urlVariables id:1
queryVariables queryParams
}
I feel this would be much more 'DRY', and easier to read/write.
Does anyone know if such a mechanism exists? I know I could put together a class to do it, but I was hoping to avoid this if there is an existing implementation.
You can do as below.
Map queryParams = [x: 'foo', y: 'bar', z: 'baz']
RestResponse response = builder.get("http://example.com/api/{id}", queryParams) {
urlVariables id:1
}
RestBuilder's get() is overloaded to accept three params: String url, Map queryParams and the RequestCustomizer closure
I felt the same awkwardness when initially using the API. Currently I'm doing something slightly more concise:
RestResponse response = builder.get("http://example.com/api/{id}?x={x}&y={y}", [id:1, x:'foo', y:'bar'])
It doesn't feel that bad, kinda same style with named sql parameters in groovy SQL
Related
I have a rest and a microservice.In microservice i have a table and i want that table data to be fetched to rest and i have written the below way in a rest demoController.
def result = restBuilder().post("http://localhost:2222/api/microservice/fetchData"){
header 'authorization', 'fdgtertddfgfdgfffffff'
accept("application/json")
contentType("application/json")
json "{'empId':1,'ename':'test1'}"
}
But it throws an error "No signature of method: demoController.restBuilder() is applicable for argument types: () values: []".How should i fetch data from a microservice to rest?
You are calling a method named restBuilder() and that method does not exist. If you want that to work, you will need to implement that method and have it return something that can deal with a call to post(String, Closure).
You probably are intending to use the RestBuilder class. The particulars will depend on which version of Grails you are using but you probably want is something like this...
RestBuilder restBuilder = new RestBuilder()
restBuilder.post('http://localhost:2222/api/microservice/fetchData'){
header 'authorization', 'fdgtertddfgfdgfffffff'
accept 'application/json'
json {
empId = 1
name = 'test1'
}
}
You may need to add a dependency on grails-datastore-rest-client in your build.gradle.
compile "org.grails:grails-datastore-rest-client"
I hope that helps.
I want to look at the full URL the HTTParty gem has constructed from my parameters, either before or after it is submitted, it doesn’t matter.
I would also be happy grabbing this from the response object, but I can’t see a way to do that either.
(Bit of background)
I’m building a wrapper for an API using the HTTParty gem. It’s broadly working, but occasionally I get an unexpected response from the remote site, and I want to dig into why – is it something I’ve sent incorrectly? If so, what? Have I somehow malformed the request? Looking at the raw URL would be good for troubleshooting but I can’t see how.
For example:
HTTParty.get('http://example.com/resource', query: { foo: 'bar' })
Presumably generates:
http://example.com/resource?foo=bar
But how can I check this?
In one instance I did this:
HTTParty.get('http://example.com/resource', query: { id_numbers: [1, 2, 3] }
But it didn’t work. Through experimenting I was able to produce this which worked:
HTTParty.get('http://example.com/resource', query: { id_numbers: [1, 2, 3].join(',') }
So clearly HTTParty’s default approach to forming the query string didn’t align with the API designers’ preferred format. That’s fine, but it was awkward to figure out exactly what was needed.
You didn't pass the base URI in your example, so it wouldn't work.
Correcting that, you can get the entire URL like this:
res = HTTParty.get('http://example.com/resource', query: { foo: 'bar' })
res.request.last_uri.to_s
# => "http://example.com/resource?foo=bar"
Using a class:
class Example
include HTTParty
base_uri 'example.com'
def resource
self.class.get("/resource", query: { foo: 'bar' })
end
end
example = Example.new
res = example.resource
res.request.last_uri.to_s
# => "http://example.com/resource?foo=bar"
You can see all of the information of the requests HTTParty sends by first setting:
class Example
include HTTParty
debug_output STDOUT
end
Then it will print the request info, including URL, to the console.
As explained here, if you need to get the URL before making the request, you can do
HTTParty::Request.new(:get, '/my-resources/1', query: { thing: 3 }).uri.to_s
I am attempting to create an odata url with multiple breeze.js passthrough predicates using documentation from the folowing link: http://www.getbreezenow.com/documentation/query-using-json.
However the generated url looks nothing like an odata url eg:
var query = breeze.EntityQuery.from('User').using(this.manager).where("{ { 'userName': { '=': '123456' } } }");
var url = query._toUri(this.manager);
url is "User?$filter=%7B%20%7B%20'userName'%3A%20%7B%20'%3D'%3A%20'123456'%20%7D%20%7D%20%7D&$orderby=UserName" rather than "User?$filter=(UserName eq '123456')&$orderby=UserName".
I don't think you want a passthru query because this just passes your where clause thru intact without any processing. This is what happens when you quote the entire where clause.
If you want your query converted to 'odata' syntax then try the following:
var query = breeze.EntityQuery.from('Customers').using(em)
.where({ 'userName': { '==': '123456' } });
Note that the 'where' argument is NOT in quotes ( it is a standard javascript object), and the operator is '==', not '=';
or even simpler
var query = breeze.EntityQuery.from('Customers').using(em)
.where( { userName: '123456' });
Further info:
There are two forms of urls that can be generated from any breeze query. An OData form and a JSON form. If you want OData, (the default) then you either do nothing because it is the default or you can tell breeze explicitly with:
breeze.core.config.initializeAdapterInstance("uriBuilder", "odata");
If you want the json form, you would use
breeze.core.config.initializeAdapterInstance("uriBuilder", "json");
It also possible that you added a line to use the 'json' uriBuilder. Just omit this line if you want OData urls. You can still construct the query via the json syntax, but the URL will be output using OData syntax.
The Json form ( or uri) is useful for non OData servers.
By design, GET operation should be used only for read Only operation. Howeevre,i am looking for a plausible way of implementaion of following.Implement a POST operation that can be called as it is mentioned below
POST /my-store/order/D : where D is the day the customer place an order
Request: POST /my-store/order/14
{
"customer" : "XYZ",
"order" : {
"item1" : 2
}
}
I tried implementing using below function
#Path("/D")
#POST
#Consumes({ MediaType.TEXT_PLAIN, MediaType.APPLICATION_JSON })
#Produces({ MediaType.APPLICATION_JSON })
public Response submitOrder(#PathParam("D") int elapsedDays, #Context UriInfo uriInfo, Order orderInfo){
..........
}
But the above implementation does not seem to working. When I try to test the implementation using MyEclipse REST explorer ,it does not offer option to pass in Order object but allow 'D' parameter only. However, if #PathParam and #Path is removed then it works perfectly fine i.e. allows to consume JSON Order object.
But,the requirement is to pass the days as Path parameter and Order object as JSON input in POST request.
Looking for suggestion on implementation approach and design approach.
Thanks in advance
For one thing, your path should be configured like this:
#Path("/{D}")
I assume your extended ellipses means you have some method parameter that represents the deserialization of your order.
I am trying to get my Actionscript program to turn in a key-value (more specifically: a key, value1, value2) object into a server. I am doing the html request properly, but I'm not sure what kind of object to send; can anyone help?
--Thanks
When I understand correctly you want to post an object to the server, which has 1 key and multiple values. The latter is not supported by a HTTP_POST/GET call, you could however use something as AMF to send a VO from Flash over to a server and decode the AMF object on the server. Not sure whether or not that is where you are looking for, or you just want to post 2 values to a server.
Posting 2 values to a server is simple, but it requires two keys.
public function URLVariablesExample() {
var url:String = "http://www.domain.com/script.php";
var request:URLRequest = new URLRequest(url);
var variables:URLVariables = new URLVariables();
variables.keyOne = new Date().getTime();
variables.keyTwo = "Something";
request.data = variables;
navigateToURL(request);
}