grape-api - Force empty string to set values to null - ruby-grape

I am creating an API endpoint which contains a file upload field and a few string fields. My goal is to allow clients to clear values on those string fields, i.e. the DB should persist these values as null.
However, due to the fact that the request may contain files, the client should be setting the Content-type header to multipart/form-data. This implies that client cannot send a representation of "null", but can only send an empty string to indicate the intent of clearing the value for a given string field.
Is there a way for grape-api library to know that when it is receiving a multipart request it should be able to nullify blank string values in the params, or is there a better approach to what I am trying to achieve?

Grape.configure do |config|
config.param_builder = Grape::Extensions::Hashie::Mash::ParamBuilder
end
you can override the param builder. extend the default one and override the build_params method or monkey patch it.
params.transform_values {|v| v.eql?('') ? nil : v }

Related

How to check if a value is present in a POST form with Go's net/http?

According to the documentation:
PostFormValue returns the first value for the named component of the POST, PATCH, or PUT request body.
URL query parameters are ignored.
PostFormValue calls ParseMultipartForm and ParseForm if necessary
and ignores any errors returned by these functions.
If key is not present, PostFormValue returns the empty string.
So the function Request.PostFormValue(key string) string returns an empty string when key does not exist in the POST body, but also when it exists and its value is empty.
How can I only check if the key is in the POST body, regardless of its value?
Parse the form and then check to see if the key is set in the post form.
req.ParseForm()
hasKey := req.PostForm.Has("key")

How to serialize empty string to selfclosing tag

Using JMS Serializer
I need to get self closing tag setting empty string
<logout/>
I always get
<logout></logout>
I can't use
->setSerializeNull(true)
because the class I'm serializing has many properties that if they are null they can't be serialized
Any idea how to get it done ?

go properly handling slices and strings

I am using goRequest http://parnurzeal.github.io/gorequest/ to make some HTTP requests against a server process I need to talk to. The authentication process works like this;
send in a GET request with an authentication header set. No problem there, but I need to grab a header from the response and use a returned value to reauthenticate each following request.
The retuned HTTP header looks like this.
Response headers
map[Location:[900767244] Content-Type:[application/xml] Date:[Fri, 18 Sep 2015 18:19:41 GMT] Server:[Apache] X-Frame-Options:[SAMEORIGIN] Set-Cookie:[JSESSIONID=D5C976F5646365FF030DBAD770DA774C; Path=/; Secure; HttpOnly]]
I need to get that location value as it's my session token going forward. If I grap it like this:
session, ok := response.Header["Location"]
if !ok {
fmt.Println("Did not receive a location header.")
}
fmt.Println("Session: ", session)
I can get it, but it's a slice and NOT a string. How can I get that value as a string so I can pop it back into my request headers going forward? As you can see in the following error:
./login.go:133: cannot use session (type []string) as type string in argument to logoutRequest.Delete
Thanks a lot!
Craig
If you want one value, use the Header's Get method
location := response.Header.Get("Location")
This also canonicalizes the header name for you, so that you still get a value even when using slightly different capitalization.
You only need to index an http.Header value directly when you need to get more than than the first possible value. If you want all values with a canonicalized header name, you can use textproto.CanonicalMIMEHeaderKey
vals := response.Header[textproto.CanonicalMIMEHeaderKey(header)]
The headers have location as an array, you just need to pass Location[0] to that method rather than simply Location because it is a slice. That being said, indexing into the array without checking the bounds is unsafe so you should probably do;
if len(Location) == 1 {
logoutRequest(Location[0])
} else {
// error state
}
One last thing to provide you guidance in the future. You can tell that the response headers object has a type more like this; map[string][]string (in reality that maybe []interface{} but I'm not certain from the output) by seeing that each item inside the outer brackets [] has it's values contained within another set of brackets, meaning it is an array that could contain 0 or more values.

Spring request mapping wildcard exceptions

Can I put /** wildcard in a middle of request mapping such as: "/some/resource/**/somthing"
In Spring 3 I can do this
#RequestMapping("/some/resource/**")
to map
/some/resource/A -> ControllerMethod1
/some/resource/A/B -> ControllerMethod1
/some/resource/A/B/C/D/E/F -> ControllerMethod1
for any number of paths parts
However this mapping is too greedy and will not allow me to map a sub URL #RequestMapping("/some/resource/**/somthing") to another controller such as
/some/resource/A/somthing -> ControllerMethod2
/some/resource/A/B/somthing -> ControllerMethod2
/some/resource/A/B/C/D/E/F/somthing -> ControllerMethod2
How can i do this?
I thinks it's not possible to use that ant style in url mapping as you require, because it will stop on the next path separator character '/'.
I would suggest you to try 16.3.2.2. URI Template Patterns with Regular Expressions in order to map just the last part of the request (haven't tried this approach yet).
Also you can match the rest of the request using PATH_WITHIN_HANDLER_MAPPING_ATTRIBUTE, and apply some expression there. Check this post.
Otherwise you should use request parameters to match that condition 16.3.2.6. Request Parameters and Header Values.
You can narrow request matching through request parameter conditions such as "myParam", "!myParam", or "myParam=myValue". The first two test for request parameter presense/absence and the third for a specific parameter value. Here is an example with a request parameter value condition.
In this case you will map something like that using params
#RequestMapping(value = {"/some/resource/**"}, params="somthing")
or use the annotation request parameter with not required attribute in method signature:
public void test(#RequestParam(value = "somthing", required=false) String str) {

How to use "Result Variable Name" in JDBC Request object of Jmeter

In JMeter I added the configuration for oracle server. Then I added a JDBC request object and put the ResultSet variable name to status.
The test executes fine and result is displayed in treeview listener.
I want to use the variable status and compare it with string but jmeter is throwing error about casting arraylist to string.
How to retrieve this variable and compare with string in While Controller?
Just used some time to figure this out and think the accepted answer is slightly incorrect as the JDBC request sampler has two types of result variables.
The ones you specify in the Variable names box map to individual columns returned by your query and these you can access by saying columnVariable_{index}.
The one you specify in the Result variable name contains the entire result set and in practice this is a list of maps to values. The above syntax will obviously not work in this case.
The ResultSet variable returned with JDBC request in JMeter are in the for of array. So if you want to use variable status, you will have to use it with index. If you want to use the first(or only) record user status_1. So you need to use it like status_{index}.
String host = vars.getObject("status").get(0).get("option_value");
print(host);
log.info("----- " + host);
Form complete infromation read the "yellow box" in this link:
http://jmeter.apache.org/usermanual/component_reference.html#JDBC_Request
Other util example:
http://jmeter.apache.org/usermanual/build-db-test-plan.html
You can use Beanshell/Groovy (same code works) in JSR233 PostProcessor to work with “Result Variable Name” from JDBC Request like this:
ArrayList results = vars.getObject("status");
for (HashMap row: results){
Iterator it = row.entrySet().iterator();
while (it.hasNext()){
Map.Entry pair = (Map.Entry)it.next();
log.info(pair.getKey() + "=" + pair.getValue());
}
}
Instead of output to log replace with adding to string with delimiters of your choice.

Resources