See the [Documentation Style Guide RESTful API section](documentation/styleguide.md#restful-api) for details on documenting API resources in Markdown as well as in OpenAPI definition files.
- The GitLab version when the endpoint was added. If it is behind a feature flag, mention that instead: _This feature is gated by the :feature\_flag\_symbol feature flag._
Prior to Grape v1.3.3, Array parameters with `nil` values would
automatically be coerced to an empty Array. However, due to [this pull
request in v1.3.3](https://github.com/ruby-grape/grape/pull/2040), this
is no longer the case. For example, suppose you define a PUT `/test`
request that has an optional parameter:
```ruby
optional :user_ids, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The user ids for this rule'
```
Normally, a request to PUT `/test?user_ids` would cause Grape to pass
`params` of `{ user_ids: nil }`.
This may introduce errors with endpoints that expect a blank array and
do not handle `nil` inputs properly. To preserve the previous behavior,
there is a helper method `coerce_nil_params_to_array!` that is used
in the `before` block of all API calls:
```ruby
before do
coerce_nil_params_to_array!
end
```
With this change, a request to PUT `/test?user_ids` will cause Grape to
pass `params` to be `{ user_ids: [] }`.
There is [an open issue in the Grape tracker](https://github.com/ruby-grape/grape/issues/2068)
For non-200 HTTP responses, use the provided helpers in `lib/api/helpers.rb` to ensure correct behavior (`not_found!`, `no_content!` etc.). These will `throw` inside Grape and abort the execution of your endpoint.
For `DELETE` requests, you should also generally use the `destroy_conditionally!` helper which by default returns a `204 No Content` response on success, or a `412 Precondition Failed` response if the given `If-Unmodified-Since` header is out of range. This helper calls `#destroy` on the passed resource, but you can also implement a custom deletion method by passing a block.
`/etc/passwd/`. By default, absolute paths are not allowed. However, you can optionally pass in an allowlist for allowed absolute paths in the following way:
The [`Git SHA` validator](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/validations/validators/git_sha.rb)
checks whether the Git SHA parameter is a valid SHA.
It checks by using the regex mentioned in [`commit.rb`](https://gitlab.com/gitlab-org/gitlab/-/commit/b9857d8b662a2dbbf54f46ecdcecb44702affe55#d1c10892daedb4d4dd3d4b12b6d071091eea83df_30_30) file.
-`Absence`:
The [`Absence` validator](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/validations/validators/absence.rb)
checks whether a particular parameter is absent in a given parameters hash.
-`IntegerNoneAny`:
The [`IntegerNoneAny` validator](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/validations/validators/integer_none_any.rb)
checks if the value of the given parameter is either an `Integer`, `None`, or `Any`.
It allows only either of these mentioned values to move forward in the request.
-`ArrayNoneAny`:
The [`ArrayNoneAny` validator](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/validations/validators/array_none_any.rb)
checks if the value of the given parameter is either an `Array`, `None`, or `Any`.
It allows only either of these mentioned values to move forward in the request.
### Adding a new custom validator
Custom validators are a great way to validate parameters before sending
them to platform for further processing. It saves some back-and-forth
from the server to the platform if we identify invalid parameters at the beginning.
If you need to add a custom validator, it would be added to
it's own file in the [`validators`](https://gitlab.com/gitlab-org/gitlab/-/blob/master/lib/api/validations/validators) directory.
Since we use [Grape](https://github.com/ruby-grape/grape) to add our API
we inherit from the `Grape::Validations::Base` class in our validator class.
Now, all you have to do is define the `validate_param!` method which takes
in two parameters: the `params` hash and the `param` name to validate.
The body of the method does the hard work of validating the parameter value
and returns appropriate error messages to the caller method.
Lastly, we register the validator using the line below:
When writing tests for new API endpoints, consider using a schema [fixture](./testing_guide/best_practices.md#fixtures) located in `/spec/fixtures/api/schemas`. You can `expect` a response to match a given schema: