Selecting response elements with GPath in REST Assured

Hey, another post on REST Assured! This time I’d like to take a closer look at how you can select elements from a JSON or XML response to check their values. For this, REST Assured uses GPath, a path expression language integrated into the Groovy language. It is similar to XPath for XML, but GPath can handle both XML and JSON. This makes it an excellent fit for checking responses of RESTful web services. Read more on GPath here or here.

To see how GPath works and how you can use it effectively in REST Assured tests, let’s consider the following JSON response from the Ergast MRD API. This response lists all drivers for the 2016 Formula 1 season:

JSON response containing all Formula 1 drivers for the 2016 season

You can see the full response by selecting (or otherwise performing a GET call to) this link.

Extracting a single element value
Say we want to extract the driverId of the last driver and check that it is equal to wehrlein. Like with XPath, you can simply specify the path to the element starting with the root node and navigating through the tree until the required node is reached. Note that the index [-1] is used by GPath to denote the last matching element.

public void extractAndCheckSingleValue() {

Extracting a set of element values
Another check we might want to perform is that the collection of driverId values contains some specific values. This is done using a GPath expression very similar to the previous example:

public void extractAndCheckMultipleValues() {

Using the REST Assured base path
By now, you might have noticed that in every GPath expression we needed to start navigating from the root node MRData downwards. This results in quite long GPath expressions. REST Assured has a nifty little feature that can simplify these expressions by having you define a BasePath:

public void initPath() {
	RestAssured.rootPath = "MRData.DriverTable.Drivers";

This cleans up our tests and has a positive effect on maintainability:

public void extractAndCheckMultipleValues() {

Extracting a specific subset of values
GPath also supports array slicing to retrieve specific subsets of a collection of values. In the example below, we check that the collection of elements with index [0] through [2] has exactly three items (the ones at index [0], [1] and [2]):

public void extractAndCheckArraySliceSize() {

Filtering values
Using GPath, you can also filter values to return an even more specific subset of values. For example, if we only want to return the collection of permanentNumber values in use this year that are between 20 and 30 inclusive, we can do this:

public void extractAndCheckRange() {
		body("findAll{Drivers->Drivers.permanentNumber >= \"20\" && Drivers.permanentNumber <= \"30\"}.permanentNumber",hasItem("22")).
		body("findAll{Drivers->Drivers.permanentNumber >= \"20\" && Drivers.permanentNumber <= \"30\"}.permanentNumber",not(hasItem("33")));

The quotes around the lower and upper boundary are required since the API call returns the permanentNumber values as strings instead of integers.

Use parameters
To make the previous example a little more flexible, we can parameterize both the lower and upper boundaries as well as the values that are expected to be (or not to be) in the resulting collection. Let’s specify these in a TestNG DataProvider first:

@DataProvider(name = "rangesAndValues")
public String[][] createTestDataObject() {
	return new String[][] {

Now we can apply these in our test:

@Test(dataProvider = "rangesAndValues")
public void extractAndCheckRangeParameterized(String lowerLimit, String upperLimit, String inCollection, String notInCollection) {
		body("findAll{Drivers->Drivers.permanentNumber >= \"" + lowerLimit + "\" && Drivers.permanentNumber <= \"" + upperLimit + "\"}.permanentNumber",hasItem(inCollection)).
		body("findAll{Drivers->Drivers.permanentNumber >= \"" + lowerLimit + "\" && Drivers.permanentNumber <= \"" + upperLimit + "\"}.permanentNumber",not(hasItem(notInCollection)));

Note that the syntax gets a little messy here, especially since we have to keep the escaped double quotes in the GPath expression. There might be an easier way to do this, but I haven’t found one that still supports the given()/when()/then() format. Any pointers on this are well appreciated!

Sample code
You can download a Maven project containing all the code examples presented in this blog post here.

45 thoughts on “Selecting response elements with GPath in REST Assured

  1. Pingback: Java Web Weekly, Issue 127 | Baeldung

  2. Sorry for the double post but my code examples didn’t get rendered correctly. I’m trying with gists instead.


    Nice blog post. Just wanted to mention that you can also use single quotes in GPath expressions to make them more readable. And you can also use “withArgs” if you like. For example:

    But as you can see the path is duplicated, so you could specify a root path:

    But in this particular case (since the args are also duplicated) an alternative would be to use compose the Hamcrest matchers:

    But I suppose it’s a matter of taste.

  3. Hey Johan,

    thanks a lot for those suggestions! I wasn’t aware of the possibility to use withArgs in GPath, not did I see composite Hamcrest matchers before, so you’ve managed to teach at least one person something new. Will definitely use those (where applicable of course) in future posts and REST Assured projects / workshops / …

    I took the liberty of trashing your first comment as it was indeed rather unreadable..

  4. Pingback: Testing Bits – 5/29/16 – 6/4/16 | Testing Curator Blog

    • Whoops.. Completely forgot to upload the project! Will do so later tonight. Thanks for pointing this out to me!

      EDIT: Fixed!

  5. Hello 🙂 Great article. I have some question . How I can get driver json from array if in json will not have attribute “Drivers”. Also i want to filtr this driver json object.

  6. Hi Bas,
    Thanks for the article.

    FYI: I just downloaded the code and one of the tests is now failing. Not sure if the data changed since you wrote the test…
    FAILED: extractAndCheckRangeParameterized(“30”, “40”, “33”, “31”)
    java.lang.AssertionError: 1 expectation failed.
    JSON path MRData.DriverTable.Drivers.findAll{Drivers->Drivers.permanentNumber >= “30” && Drivers.permanentNumber <= "40"}.permanentNumber doesn't match.
    Expected: not a collection containing "31"
    Actual: [31, 30, 33]


  7. Hi Bas,

    Can you please suggest some resources for learning API test automation using SOAPUI.

    For learning API (receiving JSON responses) test automation, should I go for SOAPUI or REST Assured.


    • Rajat,
      I am also trying to learn these tools for automated REST testing.

      You may want to look at POSTMAN, it may not be the tool you use to do your actual automation, but for me it is a great tool for learning REST and JSON. This was a great video: youtube: POSTMAN RESTful API testing app demo. You can use this in combination with Newman and run automated tests via Jenkins.

      In addition to this I also setup Fiddler. This is a packet sniffer similar to Charles and Wireshark. It works on Windows and Linux, not sure about Mac (probably). This is nice because you can see what is being sent and received via your REST communication. Not sure if Bas has any articles on Fiddler, if not it would be great to see one (hint, hint)

      I’m also using TestNG with Rest-Assured, looks like a great tool. However, I’m getting a bit hung up with GPATH and non-friendly json (my term). It would be nice if there was a Rest-Assured-GPATH test site.

      I have used SoapUI for testing Soap msgs but not REST. I have used the Groovy capabilities within SoapUI, it could be a good fit for REST as GPATH is a groovy lib.

      It never hurts to have a bunch of tools in your tool box


      PS – this is a great site for test automation, keep up the good work Bas!

  8. Hi, Your blog topics are very much relevant to a newbie as well as a experienced tester. I keep referring to your blogs to find answers to my questions. I also try to follow why, what, how approach. After you introduced RESTASSURED my life has become so much easy. Earlier I was using Apahce HttpComponents.

  9. Hello, Bas
    Thank you, very usefull topics in your blog!
    Can you tell me, please, how to parse json response and put values to another response? Thank you.

  10. Hi,

    I have a question about the below response.

    Generally if I have to extract just one element, I do like this.

    boolean isJoin = Response.then()
    .contentType(ContentType.JSON) //

    Now my requirement is I would need to extract participantId for the eventType “MEETING_JOINED” and name “b”

    Could you please help in this one?

    “lastSeqNum”: 47727,

    “events”: [
    “eventType”: “MEETING_STARTED”,
    “timestamp”: “2018-01-04T19:21:11.440Z”,

    “eventType”: “MEETING_JOINED”,
    “timestamp”: “2018-01-04T19:21:11.640Z”,
    “participantId”: “d9ivt8n6st6wk5fphbway9b2s”,
    “name”: “b”,

    “eventType”: “CONTENT_CREATED”,
    “timestamp”: “2018-01-04T19:21:11.655Z”,

    “eventType”: “AUDIO_MEETING_STARTED”,
    “timestamp”: “2018-01-04T19:21:12.438Z”
    “eventType”: “MEETING_JOINED”,
    “timestamp”: “2018-01-04T19:26:47.705Z”,
    “participantId”: “j2szhbsmc58laqe3r6nrttre”,
    “name”: “a”,


    • That would be something like path(“events.find{it.eventType==’MEETING_JOINED’ AND’b’}.participantId”)


      path(“events.find{it.eventType==’MEETING_JOINED’ &&’b’}.participantId”)

      or path(“events.find{it.eventType==’MEETING_JOINED’}.findAll{’b’}.participantId”)

      Not sure about the syntax for multiple conditions and I’m too lazy to try.

      • Thank You Bas for the response. It worked.

        Now I got a different question.
        JSONArray events =, “$[?( == ‘ABC’ && @.eventType == ‘MEETING_JOINED’)]”);



        I would need to assert this output to make sure it contains participantId:”3bc9qkw48ucdpwxm4ymxrqjgs”.

        Note: we cannot go by index here.

        Could you please clarify when you get a chance?

        Thank You!

        • That shouldn’t be too hard.. I think if you simply append .participantId to that JsonPath expression, you’ll get a JSONArray of participant ID’s for which the boolean expressions hold true. Then you can simply apply a Hamcrest matcher or another method that asserts whether an array contains a specific item.

  11. Hello Bas,

    I am using to calculate the json path which allows to use the tokes like ‘?’ , ‘@’ etc

    I am trying to use the same in rest assured. But apparently, it fails to compile. The code is below

    Response resp = given().get(“”);


    Compilation Error:

    java.lang.IllegalArgumentException: Invalid JSON expression:
    Script1.groovy: 1: unexpected token: [ @ line 1, column 64.

    1 error

    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(
    at org.testng.RemoteTestNGStarter.main(
    Caused by: org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed:
    Script1.groovy: 1: unexpected token: [ @ line 1, column 64.

    Any idea how do I resolve this ?

    • REST Assured uses the GPath syntax and I don’t think the @ is supported there. Could you try this instead?


  12. Hi Bas,

    I am new to restassured. I am trying to learn. I am facing issued with parsing with Json.

    “coord”: {
    “lon”: -0.13,
    “lat”: 51.51
    “weather”: [
    “id”: 300,
    “main”: “Drizzle”,
    “description”: “light intensity drizzle”,
    “icon”: “09d”
    “base”: “stations”,
    “main”: {
    “temp”: 280.32,
    “pressure”: 1012,
    “humidity”: 81,
    “temp_min”: 279.15,
    “temp_max”: 281.15
    “visibility”: 10000,
    “wind”: {
    “speed”: 4.1,
    “deg”: 80
    “clouds”: {
    “all”: 90
    “dt”: 1485789600,
    “sys”: {
    “type”: 1,
    “id”: 5091,
    “message”: 0.0103,
    “country”: “GB”,
    “sunrise”: 1485762037,
    “sunset”: 1485794875
    “id”: 2643743,
    “name”: “London”,
    “cod”: 200

    I am using


    my IDE says hasItems is not rite. Should i include import any class to get it working. Please help

    • i am trying to see if the returned city is London. At a high level i am trying to learn to parse a Json in rest assured. TIA!!!

    • If you imported org.hamcrest.Matchers.* statically then you should be fine import-wise.

      However, you’re making two mistakes here:

      1. You’re passing a single item to the hasItems() matcher, where it takes a collection of items (you’re looking for hasItem() instead)
      2. hasItem() won’t work here either because that one is meant to check whether a given item is in a list (an array) of results. For this specific response and check, you’re checking equality of a single response value (the value of the element ‘name’) against an expected value. The correct matcher to use here is equalTo()
  13. Hey Bas,

    Nice and clear post. I had a question about finding a specific element.

    name: “Sean”

    Now when I try to find the age of sean ill do
    body(“findAll {Person -> == ‘sean’}”

    it will say name was used but not defined. Do you have any idea what could be wrong? I used the roothPath = data.Person,

  14. Invalid JSON expression is appeairing if i am using string variable in following statement

    String supportsStatementsValue = response.path(“accounts.find{it.desc ==” + ExpectedAccountDesc + “}.supportsStatements”).toString();

    Whereas it is working fine if I use the following

    String=supportsStatementsValue =
    response.path(“accounts.find{it.desc ==’1st account'” }.supportsStatements”).toString();

    Please help me.

    • What’s the value of ExpectedAccountDesc? Does it include single quotes? Properly escaped? String concatenations like these are tricky!

      • Thanks Bas.
        Values are like 1st Account or Savings Account or any other string.
        In JSON, these values are appearing in double quotes e.g “1st Account” or “Savings Account”.

        As mentioned above, i tried with following also but didn’t work.

        String supportsStatementsValue =
        response.path(“accounts.find{it.desc ==’1st account’” }.supportsStatements”).toString();

        • It looks like there’s one quote too many there if that’s your literal statement, I think it should be

          String supportsStatementsValue = response.path(“accounts.find{it.desc ==’1st account’}.supportsStatements”).toString();

          • Thanks Bas. IT is working fine if i am hard coding the value in single quotes. But i am captruing the value in string variable 1st and then using that variable. It is at this point, i am receiving that error.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.