Using the API

Any API client supporting REST architecture can be used to make calls to Squore REST API, like cURL, Postman, or else.

Squore REST API offers several features that can help you better understand and/or customize the API responses, you will find their descriptions in the following sections.

Version

In order to provide better flexibility and allow for backward compatibility, the Squore REST API is versioned. Current version for the REST API is: v2.

The version is set up in the API request header with the accept parameter, as follows:

  • accept: application/vnd.squore.app-<version>+json.

Note that you can also use the value, latest, if you want your API request to always use the latest available version of the API known to Squore server.

Example of version latest specified in header using cURL
curl -X GET "http://localhost:8180/api/projects" -H "accept: application/vnd.squore.app-latest+json" -H "Authorization: Bearer <token>"
Example of version v2 specified in header using cURL
curl -X GET "http://localhost:8180/api/projects" -H "accept: application/vnd.squore.app-v2+json" -H "Authorization: Bearer <token>"

If no version is specified in the header, then the default version specified in Administration > System page is used (Configuring API Default Version). If multiple headers are defined, then the most recent API version is used.

Filters

Filters can be used to reduce/customize the API requests responses.

Squore REST API offers two filtering methods:

  • Filtering the data to reduce the API requests scope and improve performances

  • Filtering the JSON response fields to improve the response readability and/or processing

Filtering Data

Filtering the data will help you reduce the API requests scope and improve performances.

To filter the data, the keyword where must be added at the end of the URI, followed by the filtering expression. The syntax is inspired by SQL/JQL but with some particularities because it is used in a URI.

Understanding the filtering syntax:

…​/api/projects?where=(analysisTime!=2020-12-25 OR analysisTime!=2020-12-24)

Where:

  • ?where= is the keyword for introducing the filtering query.

  • (…​) are the parenthesis used to group conditions.

  • analysisTime is the JSON field we want to compare to.

  • != is the comparison operator.

  • 2020-12-25 is the comparison value.

  • OR is a logical operator, make sure to add spaces before and after the operator.

Supported JSON fields are the ones from the JSON responses and supported data types are, strings, booleans, integers and dates (with format yyyy-MM-dd, without the time).

Sub-levels arrays cannot be filtered. In the example below :

  • …​/api/projects?where=(name=Kaptcha) is valid

  • …​/api/projects?where=(branches.name=main) is not valid

{
    "_links": {
        "self": "/projects"
    },
    "projects": [{
            "_links": {
                "self": "/projects/11"
            },
            "id": 11,
            "name": "Kaptcha",
            ...
            "branches": [{
                    "id": 16,
                    "name": "main",
                    "versionId": 46,
                    ...

If comparison value contains special characters (space, parenthesis, etc…​), the value must be surrounded by double quotes. And in case the special characters are double quotes, they need to be escaped by being doubled, as follows:

  • …​/api/projects?where=(name="my name").

  • …​/api/projects?where=(name="my name ""with double"" quotes").

Logical Operators

  • OR returns true if at least one operand evaluates to true.

  • AND returns true if both operands evaluates to true.

  • IN returns true if the field value is in the provided list of values.

  • NOT IN returns true if the field value is not in the provided list of values.

  • IS NULL returns true if the field value equals NULL.

  • IS NOT NULL returns true if the field value does not equal NULL.

Logical operators need to be surrounded by spaces, one before and one after.

Comparators

  • Equals, = : returns true if both operands are equals.

  • Not equals, != : returns true if both operands are not equals.

  • Greater than, > : returns true if left operand is greater than right operand.

  • Greater than or equal, >=: returns true if left operand is greater than or equal to right operand.

  • Less than, < : returns true if left operand is less than right operand.

  • Less than or equal, <= : returns true if left operand is less than or equal to right operand.

  • Contains, ~ : returns true if the left operand contains the string specified as right operand.

  • Starts with, ~test* : returns true if the left operand starts with the specified string, test, followed by anything.

  • Ends with, ~*test : returns true if the left operand ends with the specified string, test, preceded by anything.

Examples

Filtering projects with global rating lower than B amongst Earth, Mars, Venus and Pluto
.../api/projects?where=(name IN (Earth,Mars,Venus) OR name=Pluto) AND level.id NOT IN (LEVELA,LEVELB)
Filtering artefacts of type FOLDER on project Earth with rating higher than or equal to D
.../api/projects/Earth/artefacts?where=type.id=FOLDER AND rank>=0.125
Filtering file artefacts with extension ".c" on project Earth
.../api/projects/Earth/artefacts?where=name~*.c

Depending on the REST client you are using, you might have to encode the URI as follows:

.../api/projects?where=type.id%3DFOLDER%20AND%20rank%3E%3D0.125

Filtering Fields

Filtering fields will help you improve the JSON response parsing/processing and readability.

To filter fields, the keyword fields must be added at the end of the URI, followed by the filtering expression.

Understanding the filtering syntax:

…​/api/projects?fields=name,level.id,status(id,name)

Where:

  • ?fields= is the keyword for introducing the filtering query.

  • name, level, status are the first level JSON fields.

  • id, (id,name) are sub-levels JSON fields.

Wanted fields are separated by a coma, name,level, and sub-levels fields are accessed by a point, level.id.

If multiple sub-levels fields are expected, then the point is replaced by the list of sub-levels fields enclosed in parentheses and separated by a coma, status(id,name).

Filtering fields is not available for the following API requests, since they have their own filtering system :

  • GET /dump

  • GET /artefacts/{artefact-id}/query

  • GET /artefacts/{artefact-id}/highlights/{highlight-id}

It is also not possible to filter on the sub-levels of the _links JSON field.

Examples

Filtering JSON fields for findings
.../api/artefacts/439/findings?fields=definition.categories.level.id,definition.families
Filtering JSON nested fields for findings
.../api/artefacts/439/findings?fields=definition(families,categories(level(id,name),scale.name))

All returned items by Squore API have an attached JSON object named "links".

The links object contains the current link (self) and the information context.

Response example of the API /projects to get the projects list
{
    "_links": {
        "project": "http://localhost:8180/api/projects/9",
        "self": "http://localhost:8180/api/artefacts/4433/findings",
        "model": "http://localhost:8180/api/models/software_analytics",
        "version": "http://localhost:8180/api/versions/14",
        "artefact": "http://localhost:8180/api/versions/14/artefacts/4433"
    },
    "findings": [{
            "_links": {
                "self": "http://localhost:8180/api/findings/4502"
            },
            "id": 4502,
            "tool": "SQUORE",
            "definition": {
                "id": "R_NOASGCOND",
                "name": "Assignment in Boolean",
                "description": "Assignment operators shall not be used in expressions that yield a boolean value"
            },
            "status": "OPEN",
            "locations": [{
                    "id": 2737,
                    "artefact": {
                        "_links": {
                            "self": "http://localhost:8180/api/artefacts/4464"
                        },
                        "id": 4464,
                        "name": "machine_plays_right()",
                        "path": "mars_engine_right.c",
                        "type": {
                            "id": "C_FUNCTION"
                        }
                    },
                    "location": "Line: 438"
                }
            ],
            "readOnly": false,
            "suspicious": false
        },...]
}

Pagination

The pagination feature was implemented to avoid getting too much information at once. This feature is available for all API requests that are susceptible to retrieve many items. To use it, just provide the size and/or page parameter to the query.

cURL example to get projects from the forty-first to the fiftieth
curl -X GET "http://localhost:8180/api/projects?page=5&size=10"
-H "accept: application/json"
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjIsImlhdCI6MTU1MjQwNTgyMzYxMiwiaW50ZXJuYWwiOjAsInNlcSI6M30=.GimdyMOvhjABUHOE4B21bX2zi3q5SEvya257yjMgtWk="

The page and size are optional parameters. If the size parameter was initialized and not the page, the first page is taken by default (&page=1).

The response contains several links that will facilitate the navigation between pages (current/previous/next/first/last).

Response links example to get the projects with pagination
{
  "_links": {
    "previous": "http://localhost:8180/api/projects?page=4&size=10",
    "next": "http://localhost:8180/api/projects?page=6&size=10",
    "first": "http://localhost:8180/api/projects?page=1&size=10",
    "last": "http://localhost:8180/api/projects?page=8&size=10",
    "self": "http://localhost:8180/api/projects?page=5&size=10"
  },
  "projects": [{...}]
}

Localization

The localization feature allows to choose which language must be used for the API responses content.

By default, the language of the user who created the token is used. It is possible to force the language by passing the information in the header.

It is also possible to change the timezone, by default it is the user’s timezone.

cURL example in German and Europe/Germany timezone
curl -X GET "http://localhost:8180/api/projects"
-H "accept-language: en"
-H "timezone: Europe/Germany"
-H "accept: application/json"
-H "Content-Type: application/json"
-H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1aWQiOjIsImlhdCI6MTU1MjQ2NTg0MzE2NiwiaW50ZXJuYWwiOjAsInNlcSI6N30=.EBMsApnJ7BdIM6QYi225azgZVwb2bE7_J8TcTIEZEDQ="