I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE COURSE

1. Overview

The REST-assured library provides support for testing REST APIs, usually in JSON format.

From time to time it may be desirable, without analyzing the response in detail, to know first-off whether the JSON body conforms to a certain JSON format.

In this quick tutorial, we’ll take a look at how we can validate a JSON response based on a predefined JSON schema.

2. Setup

The initial REST-assured setup is the same as our previous article.

In addition, we also need to include the json-schema-validator module in the pom.xml file:

<dependency>
    <groupId>io.rest-assured</groupId>
    <artifactId>json-schema-validator</artifactId>
    <version>3.0.0</version>
</dependency>

To ensure you have the latest version, follow this link.

We also need another library with the same name but a different author and functionality. It’s not a module from REST-assured but rather, it’s used under the hood by the json-schema-validator to perform validation:

<dependency>
    <groupId>com.github.fge</groupId>
    <artifactId>json-schema-validator</artifactId>
    <version>2.2.6</version>
</dependency>

Its latest version can be found here.

The library, json-schema-validator, may also need the json-schema-core dependency:

<dependency>
    <groupId>com.github.fge</groupId>
    <artifactId>json-schema-core</artifactId>
    <version>1.2.5</version>
</dependency>

And the latest version is always found here.

3. JSON Schema Validation

Let’s have a look at an example.

As a JSON schema, we’ll use a JSON saved in a file called event_0.json, which is present in the classpath:

{
    "id": "390",
    "data": {
        "leagueId": 35,
        "homeTeam": "Norway",
        "visitingTeam": "England",
    },
    "odds": [{
        "price": "1.30",
        "name": "1"
    },
    {
        "price": "5.25",
        "name": "X"
    }]
}

Then assuming that this is the general format followed by all data returned by our REST API, we can then check a JSON response for conformance like so:

@Test
public void givenUrl_whenJsonResponseConformsToSchema_thenCorrect() {
    get("/events?id=390").then().assertThat()
      .body(matchesJsonSchemaInClasspath("event_0.json"));
}

Notice that we’ll still statically import matchesJsonSchemaInClasspath from io.restassured.module.jsv.JsonSchemaValidator.

4. JSON Schema Validation Settings

4.1. Validate a Response

The json-schema-validator module of REST-assured gives us the power to perform fine-grained validation by defining our own custom configuration rules.

Say we want our validation to always use the JSON schema version 4:

@Test
public void givenUrl_whenValidatesResponseWithInstanceSettings_thenCorrect() {
    JsonSchemaFactory jsonSchemaFactory = JsonSchemaFactory.newBuilder()
      .setValidationConfiguration(
        ValidationConfiguration.newBuilder()
          .setDefaultVersion(SchemaVersion.DRAFTV4).freeze())
            .freeze();
    get("/events?id=390").then().assertThat()
      .body(matchesJsonSchemaInClasspath("event_0.json")
        .using(jsonSchemaFactory));
}

We would do this by using the JsonSchemaFactory and specify the version 4 SchemaVersion and assert that it is using that schema when a request is made.

4.2. Check Validations

By default, the json-schema-validator runs checked validations on the JSON response String. This means that if the schema defines odds as an array as in the following JSON:

{
    "odds": [{
        "price": "1.30",
        "name": "1"
    },
    {
        "price": "5.25",
        "name": "X"
    }]
}

then the validator will always be expecting an array as the value for odds, hence a response where odds is a String will fail validation. So, if we would like to be less strict with our responses, we can add a custom rule during validation by first making the following static import:

io.restassured.module.jsv.JsonSchemaValidatorSettings.settings;

then execute the test with the validation check set to false:

@Test
public void givenUrl_whenValidatesResponseWithStaticSettings_thenCorrect() {
    get("/events?id=390").then().assertThat().body(matchesJsonSchemaInClasspath
      ("event_0.json").using(settings().with().checkedValidation(false)));
}

4.3. Global Validation Configuration

These customizations are very flexible, but with a large number of tests we would have to define a validation for each test, this is cumbersome and not very maintainable.

To avoid this, we have the freedom to define our configuration just once and let it apply to all tests.

We’ll configure the validation to be unchecked and to always use it against JSON schema version 3:

JsonSchemaFactory factory = JsonSchemaFactory.newBuilder()
  .setValidationConfiguration(
   ValidationConfiguration.newBuilder()
    .setDefaultVersion(SchemaVersion.DRAFTV3)
      .freeze()).freeze();
JsonSchemaValidator.settings = settings()
  .with().jsonSchemaFactory(factory)
      .and().with().checkedValidation(false);

then to remove this configuration call the reset method:

JsonSchemaValidator.reset();

5. Conclusion

In this article, we’ve shown how we can validate a JSON response against a schema when using REST-assured.

As always, the full source code for the example is available over on GitHub.

I just announced the new Spring 5 modules in REST With Spring:

>> CHECK OUT THE LESSONS