Get headers setup in RequestSpecification object

229 views
Skip to first unread message

Shreejit Nair

unread,
Apr 6, 2018, 1:28:16 PM4/6/18
to REST assured
Hi,

I was wondering if there is a way to retrieve the headers that are setup in the RequestSpecification object in restAssured.
I understand that it has functions to setup the headers but I was wondering if given a RequestSpecification object is there a way to do a get() and check what headers have been setup?


Shreejit

Todd Bradley

unread,
Apr 6, 2018, 3:22:10 PM4/6/18
to rest-a...@googlegroups.com
Sadly, there isn't. I wish the same thing. It would be nice to be able to peek inside a RequestSpecification for debugging purposes. I don't know what it would take to add that ability. If nothing else, you could write a wrapper class around RequestSpecification to do that.


Todd.

--
You received this message because you are subscribed to the Google Groups "REST assured" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rest-assured+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Johan Haleby

unread,
Apr 7, 2018, 7:30:57 AM4/7/18
to rest-a...@googlegroups.com
Well the getters are hidden intentionally since the purpose of the RequestSpecification is to construct a specification. Perhaps if I can understand your use case(s) then maybe we could figure something out.

What you could do is to cast it to a "FilterableRequestSpecification" which exposes the getters (and ability to override settings). But this is not guaranteed to work in the future and should be considered a workaround/hack.

Regards,
/Johan

Todd Bradley

unread,
Apr 7, 2018, 2:20:18 PM4/7/18
to rest-a...@googlegroups.com
In my own case, there are a few reasons I'd like for there to be getters on the various parts of a RequestSpecification:

1) Symmetry. If I can set the content type of a RequestSpecification, I should be able to get it back. I can't think of any good reason to make the values of the fields a mystery.

2) Debugging. When I'm troubleshooting some test that's gone awry, I often find myself asking, "OK, why is the Content-Type getting set to that weird value? Is it because the RequestSpecification factory is setting it, or because some other part of our test infrastructure is setting it, or because the HTTP proxy downstream is setting it?" It would be nice to peer into the RequestSpecification.

3) To cut down on questions. Every other week, some coworker asks me, "How do I find out what headers the RequestSpecification is set to use?" And I'm tired of answering, "There isn't a good way."

4) We have a RequestSpecification factory class that creates RequestSpecification instances to make testing different APIs within our set of services easier. The people who write test cases don't know and don't want to know the details of this factory - whether this particular instance uses basic authentication or token authentication, for example. In the rare cases they need to know, they want to just look inside. I guess this is a variation of #2 above.

The way we use RequestSpecification is sort of as a collection of parameters for a request that we reuse over and over for convenience. Who ever heard of a collection where you're not allowed to get the elements after you add them?


That's my own perspective,
Todd.



Johan Haleby

unread,
Apr 8, 2018, 7:22:08 AM4/8/18
to rest-a...@googlegroups.com
Thanks a lot for your comments, very helpful. Let's see if we can address them :)


On Sat, Apr 7, 2018 at 8:20 PM, Todd Bradley <to...@toddbradley.com> wrote:
In my own case, there are a few reasons I'd like for there to be getters on the various parts of a RequestSpecification:

1) Symmetry. If I can set the content type of a RequestSpecification, I should be able to get it back. I can't think of any good reason to make the values of the fields a mystery.

I hear what you're saying but I'm not sure I agree :). The way I see it is rather that these are two different concerns/contexts. If I'm creating a RequestSpecification I typically don't want to be bothered with A LOT of methods that is only for reading the values. Most of the time I don't care about this in my experience. While the analogy is probably far from perfect you might compare it to something like CQRS (or DCI). Here you explicitly separate  "commands" (actions) from queries and thus yield models that can be optimised for these two use cases. In REST Assured parlance the RequestSpecification would then be concerned with "commands", the query side might look totally different and might be implemented by another model/class.

The RequestSpecification interface is already very large and adding all the "getters" would of course make it a lot larger which I'm not very inclined to (unless it make sense of course).
 

2) Debugging. When I'm troubleshooting some test that's gone awry, I often find myself asking, "OK, why is the Content-Type getting set to that weird value? Is it because the RequestSpecification factory is setting it, or because some other part of our test infrastructure is setting it, or because the HTTP proxy downstream is setting it?" It would be nice to peer into the RequestSpecification.

This I can understand, but if you're debugging aren't you probing the actual implementation (i.e. the RequestSpecificationImpl)? This class contains all the state you'd want. I understand that if you're looking for calling methods directly on the interface during inspection or something then it might be a bit more troublesome. And wouldn't it be fine to just cast it to a FilterableRequestSpecification in these cases?

Also I can't recall myself ever having the need to do this. I typically just add a "log().all()" and re-run the tests (but of course this will not tell you from which specification the values come from).
 

3) To cut down on questions. Every other week, some coworker asks me, "How do I find out what headers the RequestSpecification is set to use?" And I'm tired of answering, "There isn't a good way."


Oh :/ This is usually a good indicator that something is wrong.

 
4) We have a RequestSpecification factory class that creates RequestSpecification instances to make testing different APIs within our set of services easier. The people who write test cases don't know and don't want to know the details of this factory - whether this particular instance uses basic authentication or token authentication, for example. In the rare cases they need to know, they want to just look inside. I guess this is a variation of #2 above.

I see, I haven't done this myself but it's of course fully valid and I now understand why you sometimes want to probe into it.
 

The way we use RequestSpecification is sort of as a collection of parameters for a request that we reuse over and over for convenience. Who ever heard of a collection where you're not allowed to get the elements after you add them?

Well that's not quite the design intention. The intention is more that of a "DSL" or fluent API used build an HTTP request.

Some suggestions:

1. We add a new class called something like RequestSpecificationQuerier that you could use like this:

RequestSpecification spec = ...
QueryableRequestSpecification querySpec = RequestSpecificationQuerier.query(spec)
Headers headers = querySpec.getHeaders();
List<Param> params = querySpec.findParams( param -> param.name().startsWith("something") );
...

2. We add a method to RequestSpecification that makes it queryable:

RequestSpecification spec = ...
QueryableRequestSpecification querySpec = spec.query()
Headers headers = querySpec.getHeaders();
List<Param> params = querySpec.findParams( param -> param.name().startsWith("something") );
...

Would that improve things? Does it make sense? Would you still prefer to have all getters directly on the RequestSpecification interface?

Regards,
/Johan

Todd Bradley

unread,
Apr 8, 2018, 10:57:31 PM4/8/18
to rest-a...@googlegroups.com
Yeah, I think that suggestion (they're both essentially the same) would help, at least for my cases. I can't speak for Shreejit, obviously. And I'm not sure the findParams method is worthwhile, but that's a whole other topic.


Cheers,
Todd.

Shreejit Nair

unread,
Apr 9, 2018, 10:09:29 AM4/9/18
to REST assured
The main reason for me as well was for debugging purposes, really to be able to easily introspect the RequestSpecification at any point in time in my test framework.
If I can cast it into an FilterableSpec to begin with should also be good enough for me. I would try the same today.

Shreejit
To unsubscribe from this group and stop receiving emails from it, send an email to rest-assured...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "REST assured" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rest-assured...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "REST assured" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rest-assured...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "REST assured" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rest-assured...@googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

--
You received this message because you are subscribed to the Google Groups "REST assured" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rest-assured...@googlegroups.com.

Johan Haleby

unread,
Apr 13, 2018, 2:50:12 AM4/13/18
to rest-a...@googlegroups.com
I've now implemented support for this using the "io.restassured.specification.SpecificationQuerier":


RequestSpecification spec = ...
QueryableRequestSpecification queryable = SpecificationQuerier.query(spec);
String headerValue = queryable.getHeaders().getValue("header");
String param = queryable.getFormParams().get("someparam");

Please try it out and give me feedback. Please try version 3.0.8-SNAPSHOT after having added the following maven repo:

<repositories>
        <repository>
            <id>sonatype</id>
            <url>https://oss.sonatype.org/content/repositories/snapshots/</url>
            <snapshots />
        </repository>
</repositories>

/Johan

To unsubscribe from this group and stop receiving emails from it, send an email to rest-assured+unsubscribe@googlegroups.com.

Todd Bradley

unread,
Apr 20, 2018, 1:19:49 PM4/20/18
to REST assured
I tried it out. It seems to work, at least for the test case I used it on. But I have two suggestions.

First, could you add a method onto RequestSpecification to return a QueryableRequestSpecification, like in your other example of usage? I think that will be easier for people to use because they don't have to remember the name of either QueryableRequestSpecification or SpecificationQuerier. They can just tack a .getSpecificationQuerier() on the end of an existing spec. And if you forget the name, the IDE will show you a list of choices, where doing it the same as in your example doesn't allow the IDE to give any hints to help you find what you want.

Second, QueryableRequestSpecification just begs for a good .toString() method, for logging purposes. I know there are a lot of fields or getters, but spitting them all out in toString() would be nice.


Thanks,
Todd.
Reply all
Reply to author
Forward
0 new messages