SonarQube Web API

Copyright © Tony's Studio 2020 - 2022


1. Intro

Web API is a convenient way to communicate with SonarQube server, but it is quite complicated at the same time.

It is recommended to use Postman to check API quickly, and the following contents are developed with API categories.

In this passage, I’ll introduce some basic SonarQube Web APIs, and how to use these stuffs to complete a analyze, emm… actually a simple scan.

If you do not have a SonarQube Server right now, you can use the example site of it: https://next.sonarqube.com/


2. Web API

In this section, API is presented in the format as shown below. Asterisk(*) is applied to required parameters. Notice that, here I only listed some relatively more important properties. For more usage, please check SonarQube Web API documentation. :)

1
[REQUEST_METHOD] API_FULL_NAME
1
2
3
[OMITABLE_PARAM]  -- MEANING
[REQUIRED_PARAM]* -- MEANING
[INTERNAL_PARAM]# -- MEANING
1
RESPONSE EXAMPLE

2.0 Preparation

Before you start, there’s one thing you have to know. SonarQube Web API use authentication by default, which is so called Basic Auth. To use API without repetitively getting 401 Unauthorized, you may have to set authorization for your request. Just set it to Basic Auth with your login and password.

image-20230204173351469

2.1 Authentication

Authenticate a user. This is the first thing to do when you want to communicate with SonarQube server.

2.1.1 login

To use many more features, you have to login first. This request doesn’t have a response.

1
[POST] api/authentication/login
1
2
[login]*    -- username
[password]* -- password

None.

2.1.2 logout

To log out.

1
[POST] api/authentication/logout

None.

None.

2.1.3 validate

Check credentials. You are validated only when response is true.

1
[GET] api/authentication/validate

None.

1
{"valid": true}

2.2 Quality Profile

This section deals with SonarQube quality profile. Err… duh.

Search quality profiles.

2.2.2 projects

List projects with their association status regarding a quality profile. See api/qualityprofiles/search in order to get the Quality Profile Key

1
[GET] api/qualityprofiles/projects
1
2
3
4
5
6
7
8
9
[key]*     -- quality profile key, can be obtained by search in 2.2.1.
[q] -- limit search to projects that contain the supplied string
[selected] -- show projects that selected this profile or not, depending
on the value, default is selected
(selected=selected) - show only selected items
(selected=deselected) - show only deselected items
(selected=all) - show all items
[ps] -- page size, greater than 0, default is 100, maximum 500
[p] -- 1-based page number, default is 1

Tips: It seems that by default none project is selected, so you may want to set selected to all to show all projects.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
{
"results": [
{
"key": "MyScs04",
"name": "MyScs04",
"selected": false
},
{
"key": "kang-s-scs-4",
"name": "kang's-scs-4",
"selected": false
},
{
"key": "my-scs",
"name": "my-scs",
"selected": false
},
{
"key": "myscs-4",
"name": "myscs-4",
"selected": false
}
],
"paging": {
"pageIndex": 1,
"pageSize": 100,
"total": 4
},
"more": false // I guess it indicates if there are more pages :P
}

2.2.3 add_project

Associate a project with a quality profile. Requires one of the following permissions:

  • ‘Administer Quality Profiles’
  • Edit right on the specified quality profile
  • Administer right on the specified project
1
[POST] api/qualityprofiles/add_project
1
2
3
[language]*       -- quality profile language, e.g. java
[project]* -- project key
[qualityProfile]* -- quality profile name

None.

Tips: Its weird, you must logout first, and then use authorization to avoid 401 Unauthorized.

2.3 Quality Gate

2.3.1 select

Associate a project to a quality gate. Requires one of the following permissions!

  • ‘Administer Quality Gates’
  • ‘Administer’ right on the specified project

I mean it! Administer permission required!

1
[POST] api/qualitygates/select
1
2
[gateName]   -- name of the quality gate
[projectKey] -- project key

None.

2.4 Projects

This section manages project existence. Requires ‘Create Projects’ permission, and remember to add authorization mentioned in 2.0 to the request!

2.4.1 create

Notice

1
[POST] api/projects/create
1
2
3
4
[name]*      -- name of the project, no longer than 500 characters.
[project]* -- key of the project, can be, and probably is convenient to be the same as name.
[mainBranch] -- key of the main branch of the project, default is main
[visibility] -- whether the created project should be visible to everyone, private or public
1
2
3
4
5
6
7
8
{
"project": {
"key": "myscs-2",
"name": "myscs-2",
"qualifier": "TRK",
"visibility": "public"
}
}

Tips: Its weird, you must logout first, and then use authorization to avoid 401 Unauthorized.

2.4.2 delete

Delete a project. Requires ‘Administer System’ permission or ‘Administer’ permission on the project.

1
[POST] api/projects/delete
1
[project]* -- project key

None.

delete has a brother - bulk_delete, which provide projects parameter to take multiple project keys separated by comma, instead of a single project.

Search for projects or views to administrate them.

2.5 Issues

To read and update issues. This is mainly used to get issues of projects after a successful scan.

Search for issues.

Require Browse permission on the specified project(s). For applications, it also requires ‘Browse’ permission on its child projects.

When issue indexation is in progress returns 503 service unavailable HTTP code.

PS:

1
[GET] api/issues/search
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[componentKeys] -- comma-separated list of component keys.
Retrieve issues associated to a specific list of components
and all its descendants. A component can be a portfolio, project,
module, directory or file.
[projects]# -- comma-separated list of project keys. To retrieve issues
associated to a specific list of projects.
(This can replace [componentKeys] to focus only on projects)
[languages] -- comma-separated list of languages, e.g. java,js
[ps] -- page size, in range [1, 500], 100 by default
[p] -- 1-based page number

----- category related
[severities] -- comma-separated list of severities, possible values are:
INFO, MINOR, MAJOR, CRITICAL, BLOCKER
[tags] -- comma-separated list of tags,
[rules] -- comma-separated list of coding rule keys, format is <repo>:<rule>
e.g. java:S1144
[types] -- comma-separated list of types, possible values are:
CODE_SMELL, BUG, VULNERABILITY, SECURITY_HOTSPOT

----- additional
[asc] -- ascending sort, possible values are 'true', 'false', 'yes, 'no',
'yes' by default.
[s] -- sort field, possible values are:
CLOSE_DATE, HOTSPOTS, FILE_LINE, SEVERITY,
CREATION_DATE, ASSIGNEE, STATUS, UPDATE_DATE
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
{
"total": 4,
"p": 1,
"ps": 500,
"paging": {
"pageIndex": 1,
"pageSize": 500,
"total": 4
},
"effortTotal": 17,
"issues": [
{
"key": "AYYbkN7mkKgvZBo1DSiT",
"rule": "java:S3038",
"severity": "MINOR",
"component": "myscs-4:src/scs/att/Content.java",
"project": "myscs-4",
"line": 19,
"hash": "2c953c12d2eb6ea958b7f3045ecf8e81",
"textRange": {
"startLine": 19,
"endLine": 20,
"startOffset": 1,
"endOffset": 37
},
"flows": [],
"status": "OPEN",
"message": "\"getInfo\" is defined in the \"IInfo\" interface and can be removed from this class.",
"effort": "2min",
"debt": "2min",
"author": "** e-mail address is hidden **",
"tags": [
"confusing"
],
"creationDate": "2022-11-14T19:31:16+0800",
"updateDate": "2023-02-04T16:34:44+0800",
"type": "CODE_SMELL",
"scope": "MAIN",
"quickFixAvailable": false,
"messageFormattings": []
},
{
// ...
},
// ...
],
"components": [
{
"key": "myscs-4:src/scs/att/Content.java",
"enabled": true,
"qualifier": "FIL",
"name": "Content.java",
"longName": "src/scs/att/Content.java",
"path": "src/scs/att/Content.java"
},
{
// ...
},
// ...
],
"facets": []
}

3. Application

Notice:

  • In this section, server name is omitted, e.g. www.server-name:9000/api/authentication/login is presented as api/authentication/login.
  • Request details are omitted, please refer to the previous section. It is recommended that you open two pages in separate vertical tabs.

3.0 Preparation

Before you start, you may want to take some advice.

SonarQube Web API is sometimes weird, if you logged in use api/authentication/login first, some request will not succeed and receive 401 Unauthorized even you added Authorization field. If you encountered this, please use api/authentication/logout to logout first. However, some other requests do not authenticate your Authorization field and relies on login!!! Karabast!

3.1 Create A Project

To perform a scan, we should create a project first. However, this procedure is not necessary, because a new project will be created when Sonar Scanner completes a successful scan. If we create a project first, we can configure it before the first scan.

1
[POST] api/projects/create

Tips: This request is a good example of 3.0. See above.

3.2 Associate Quality Profile

Default quality profile will be associated to our newly created project, and we might not want it.

1
[POST] api/qualityprofiles/add_project

3.3 Associate Quality Gate

Default quality gate will be associated to our newly created project, too.

1
[POST] api/qualitygates/select

3.4 Scan Project

SonarQube can not scan your project by itself. You have to use Sonar Scanner. Just refer to my previous post.

Analyze Java with SonarQube and SonarScanner

Remember to set sonar.projectKey and sonar.projectName to what you assigned when create the project. :)

3.5 View Issues

After a successful scan is performed, you can simple view your issues by a simple request.

1
[GET] api/issues/search

This request has a lot of parameters, but generally, you only need to specify projects parameter. It will then return all the issues of the selected projects. And if you want certain tags or types, just add them.

Be aware that there might be a lot of issues, and possibly more than 500, which is the maximum page size! You may need more than one request for different pages.

So, I guess this is it, good luck! :P