Sends a request constructed from the given `$template` and `$arguments` hashref.
Arguments that start with `-` (minus) are reserved to modify the client's behaviour and are **never** forwarded to GitLab.
Returns data received from GitLab API, either as hashref or arrayref (this depends on the request) or `undef` if the request failed (and `die_on_error` is disabled).
Additionally it saves the last [HTTP::Response](https://metacpan.org/pod/HTTP::Response) object as the `response` attribute of `$self`.
The following arguments can be used to modify [`exec_request`](#exec_request)'s behaviour:
- `-response => [0|1]`
Return both data and the [HTTP::Response](https://metacpan.org/pod/HTTP::Response) object as a list of two elements if set to true value.
```{.pl}
my ($data, $response) = $gitlab->$method(..., -response => 1);
```
- `-immortal => [0|1]`
When enabled, calls will not not carp on error even when `die_on_error` is enabled.
Recommended with `-response` option so that the status code can be inspected directly.
When used with paginated requests, returns only entries from the given page.
The number of entities in each page is by default _50_ except (of course) the last one.
It is possible to change the default page size with the `-per_page` option.
The API returns an empty response for invalid page numbers.
The method _croaks_ if used with a template without `$tmpl->{paginated}` attribute or if combined with `-iterator`.
- `-per_page => N`
Change the page size for `-page` or `-iterator` options.
The maximum allowed value by GitLab is currently `100`.
- `-iterator`
When non-zero, return an instance of [`GitLab::API::Iterator`](GitLab-API-Iterator.md) that will sequentially request pages when needed.
# Package methods
-`methods()`
```{.pl}
$methods = GitLab::API::methods();
```
Returns an arrayref of method names registered with the API.
This method __cannot__ be exported, use
```{.pl}
GitLab::API::methods()
```
to obtain the result.
# REQUEST METHODS
Request methods are methods that create requests and call GitLab API.
This package provides an easy data-driven way to create such methods with
request templates (see ["REQUEST TEMPLATES"](#request-templates) section and [`register`](#register)
method below).
Unless specified otherwise, these methods take a hash of options, e.g.
```{.pl}
$gitlab->$method(key => value, ...);
```
Generally, keys starting with the `-` (minus) characters are intended to modify the underlying `exec_request`'s behaviour and are not forwarded to GitLab.
This module contains only the [`whoami`](#whoami) API method, other methods are provided
by additional `GitLab::*` modules.
# REQUEST TEMPLATES
This section contains instruction on how to implement API request methods.
See [`GitLab::Users`](pod-GitLab-Users.md) and [`GitLab::Groups`](pod-GitLab-Groups.md) for examples.
The requests are made by calling the [`exec_request`](#exec_request) method with the following parameters:
| `method` | **[required]**`GET`, `POST`, `PUT` or `DELETE` |
| `path` | **[required]** URL relative to the URL parameter given to constructor |
| `paginated` | if set to `true`, the request will be repeated and results concatented until all items are obtained` |
| `query` | arrayref of paramters that should be passed as query string in the URL |
| `required` | arrayref of required arguments |
| `optional` | optional arguments |
| `ret` | hashref of HTTP codes whose values will be used as status messages |
| `encode` | arrayref of path components that should be URI-encoded |
The `path` value can contain placeholders in the format `<name>`, e.g. `/groups/<gid>/projects/<projid>` is a path that contains placeholders `gid` and `projid`.
When processing the template, these placeholders will automatically become __required arguments__.
Arguments specified in the `query` are _not_ required by default, hence, if missing, they will not be included in the final URL.
Additional arguments (those not mentioned in `query`) will be passed as the request content, that is, `arg=value&arg=value...`, since the request's `Content-Type` is `application/x-www-form-urlencoded` by default.
Optional arguments can be specified by the `optional` key.
The value of this key is an arrayref with strings.
As the name suggests, _required arguments_ must be provided, otherwise the [`exec_request`](#exec_request) will croak.
All values for `path` placeholders are encoded before replacement.
However, if the value can contain reserved URI characters (e.g. `'/'`), the encoding must be forced.
This can be done by specifying this placeholder in the `encode` arrayref.
## Examples
### Simple
Consider the following template hashref:
```{.pl}
my $user_by_id = {
name => "user_by_id",
method => "GET",
path => "/users/<uid>",
ret => { 404 => "User not found" },
};
```
Called as `$gitlab->exec_request($user_by_id, { uid => 10 })`, the method will replace `<uid>` placeholder with `10` and then it will call
```
GET .../api/v3/users/10
```
with empty content.
The `uid` argument is required; the method will croak if it is not present.
If the given user is not found, the method will return status `404` with reason `User not found`.
For other status codes it will return the reason provided either by GitLab or underlying HTTP client.
### Required arguments
```{.pl}
my $user_add_ssh_key = {
name => "user_add_ssh_key",
method => "POST",
path => "/users/<uid>/keys",
required => [ qw!title key! ],
};
```
This request requires arguments `title`, `key` and `uid` (since it appears in the `path`).
The latter argument will be substituted in the path, the former two will be passed in the body of the request.
### Encoding
```{.pl}
my $project_by_id = {
method => "GET",
path => "/projects/<id>",
encode => [ qw(id) ],
};
```
From API documentation, this operation returns a project with the given `id`, which can be a numerical value or a string `"NAMESPACE/PROJECT_NAME"`.
Without the `encode` parameter in the template, the following request
```{.pl}
$gitlab->project_by_id("user/project");
```
would result in the path `gitlab_url/projects/user/project` which is invalid.
The slash, as a reserved character, needs to be encoded using `encode_required` parameter for [`URI::Encode`](https://metacpan.org/pod/URI::Encode).
This option is enabled by specifying `id` in the `encode` parameter in the template.
Final URL in this case would be `gitlab_url/projects/user%2Fproject`.
### Pagination and optional arguments
```{.pl}
my $groups = {
name => "groups",
method => "GET",
path => "/groups",
query => [ qw!search! ],
paginated => 1,
};
```
When called, the request will be repeated with increasing `page` query value until all pages are returned.
These responses will be concatenated to a single one.
The method will croak if any of the returned pages is not an array.
In addition, the request __can__ have (but does not require) an argument `search` that will be passed in the query string (`...?search=$search`).
In order to make this argument required, the template would have to contain the following key:
```{.pl}
# ...
required => [ qw!search! ],
```
as well.
## Registering methods
- `register()`
```{.pl}
GitLab::API->register($template, ...);
```
Instead of modifying `GitLab::API` source to add a new method, or writing wrapper subs like this: