Defining custom REST calls

While all of the REST calls made through the XnatInterface object are done with REST-assured, you can always make direct REST-assured calls yourself if the functionality you're needing to use isn't supported (for example, because it's in a custom plugin). Just as your test can call mainInterface()/mainAdminInterface() to get an XnatInterface instance corresponding to the specified account, you can also call mainQueryBase()/mainAdminQueryBase() to get a REST-assured HTTP call base with authentication already attached. From there, you can write whatever REST call you would like. Here are some examples to get you started:


Example 1

final Map<String, Object> queryParams = new HashMap<>();
queryParams.put("group", "CONTROL");
queryParams.put("education", 12);
final String subjectId = mainQueryBase().queryParams(queryParams).put(formatRestUrl("/projects/EXAMPLE_PROJ/subjects/EXAMPLE")).
        then().assertThat().statusCode(Matchers.oneOf(200, 201)).and().extract().asString();

This example assumes that the mainUser account has subject create/edit permissions on a project with ID "EXAMPLE_PROJ" on the tested XNAT instance. Some takeaways from the example:

  1. formatRestUrl combines the server URL with "/data" and then all of the varargs arguments are also joined with "/" as the delimiter. formatXapiUrl is available analogously with "/xapi" instead of "/data".
  2. Two things are being done with the response. First, validation is applied that the response code should be either a 200 or a 201, and then the response body is extracted as a string. In this example, the subject's XNAT ID would be assigned to subjectId .


Example 2

Suppose you write the following POJO to represent an investigator in XNAT:

import java.util.List;

public class Investigator {

    private String title;
    private String firstname;
    private String lastname;
    private List<String> primaryProjects;
    private List<String> investigatorProjects;

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getFirstname() {
        return firstname;
    }

    public void setFirstname(String firstname) {
        this.firstname = firstname;
    }

    public String getLastname() {
        return lastname;
    }

    public void setLastname(String lastname) {
        this.lastname = lastname;
    }

    public List<String> getPrimaryProjects() {
        return primaryProjects;
    }

    public void setPrimaryProjects(List<String> primaryProjects) {
        this.primaryProjects = primaryProjects;
    }

    public List<String> getInvestigatorProjects() {
        return investigatorProjects;
    }

    public void setInvestigatorProjects(List<String> investigatorProjects) {
        this.investigatorProjects = investigatorProjects;
    }

}

As an example, you could create a new investigator and read the list of investigators known on the site like this:

final Investigator createdInvestigator = new Investigator();
createdInvestigator.setFirstname("Test");
createdInvestigator.setLastname("Investigator");
mainQueryBase().contentType(ContentType.JSON).body(createdInvestigator).post(formatXapiUrl("investigators")).then().assertThat().statusCode(200);
final List<Investigator> siteInvestigators = mainQueryBase().get(formatXapiUrl("investigators")).then().
    assertThat().statusCode(200).and().extract().jsonPath().getList("", Investigator.class);

Some takeaways from this example:

  1. You can explicitly set query parameters (as in example 1) or set a map as a body, but REST-assured will also serialize your object to JSON automatically if passed in the body. Note that you'll likely need a custom serializer if your POJO doesn't match the expected format of the API.
  2. You can automatically deserialize a response to a POJO (or List<MyPojo>) with REST-assured.

$label.name