2017-08-17 22:00:37 +05:30
|
|
|
|
# API styleguide
|
|
|
|
|
|
|
|
|
|
This styleguide recommends best practices for API development.
|
|
|
|
|
|
|
|
|
|
## Instance variables
|
|
|
|
|
|
|
|
|
|
Please do not use instance variables, there is no need for them (we don't need
|
|
|
|
|
to access them as we do in Rails views), local variables are fine.
|
|
|
|
|
|
|
|
|
|
## Entities
|
|
|
|
|
|
|
|
|
|
Always use an [Entity] to present the endpoint's payload.
|
|
|
|
|
|
|
|
|
|
## Methods and parameters description
|
|
|
|
|
|
|
|
|
|
Every method must be described using the [Grape DSL](https://github.com/ruby-grape/grape#describing-methods)
|
2019-12-21 20:55:43 +05:30
|
|
|
|
(see <https://gitlab.com/gitlab-org/gitlab/blob/master/lib/api/environments.rb>
|
2017-08-17 22:00:37 +05:30
|
|
|
|
for a good example):
|
|
|
|
|
|
|
|
|
|
- `desc` for the method summary. You should pass it a block for additional
|
|
|
|
|
details such as:
|
|
|
|
|
- The GitLab version when the endpoint was added
|
|
|
|
|
- If the endpoint is deprecated, and if so, when will it be removed
|
|
|
|
|
|
|
|
|
|
- `params` for the method params. This acts as description,
|
|
|
|
|
[validation, and coercion of the parameters]
|
|
|
|
|
|
|
|
|
|
A good example is as follows:
|
|
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
|
desc 'Get all broadcast messages' do
|
|
|
|
|
detail 'This feature was introduced in GitLab 8.12.'
|
|
|
|
|
success Entities::BroadcastMessage
|
|
|
|
|
end
|
|
|
|
|
params do
|
|
|
|
|
optional :page, type: Integer, desc: 'Current page number'
|
|
|
|
|
optional :per_page, type: Integer, desc: 'Number of messages per page'
|
|
|
|
|
end
|
|
|
|
|
get do
|
|
|
|
|
messages = BroadcastMessage.all
|
|
|
|
|
|
|
|
|
|
present paginate(messages), with: Entities::BroadcastMessage
|
|
|
|
|
end
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Declared params
|
|
|
|
|
|
|
|
|
|
> Grape allows you to access only the parameters that have been declared by your
|
|
|
|
|
`params` block. It filters out the params that have been passed, but are not
|
|
|
|
|
allowed.
|
|
|
|
|
|
2019-03-02 22:35:43 +05:30
|
|
|
|
– <https://github.com/ruby-grape/grape#declared>
|
2017-08-17 22:00:37 +05:30
|
|
|
|
|
2019-12-04 20:38:33 +05:30
|
|
|
|
### Exclude params from parent namespaces
|
2017-08-17 22:00:37 +05:30
|
|
|
|
|
2019-09-30 21:07:59 +05:30
|
|
|
|
> By default `declared(params)`includes parameters that were defined in all
|
2017-08-17 22:00:37 +05:30
|
|
|
|
parent namespaces.
|
|
|
|
|
|
2019-03-02 22:35:43 +05:30
|
|
|
|
– <https://github.com/ruby-grape/grape#include-parent-namespaces>
|
2017-08-17 22:00:37 +05:30
|
|
|
|
|
|
|
|
|
In most cases you will want to exclude params from the parent namespaces:
|
|
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
|
declared(params, include_parent_namespaces: false)
|
|
|
|
|
```
|
|
|
|
|
|
2019-12-04 20:38:33 +05:30
|
|
|
|
### When to use `declared(params)`
|
2017-08-17 22:00:37 +05:30
|
|
|
|
|
|
|
|
|
You should always use `declared(params)` when you pass the params hash as
|
|
|
|
|
arguments to a method call.
|
|
|
|
|
|
|
|
|
|
For instance:
|
|
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
|
# bad
|
|
|
|
|
User.create(params) # imagine the user submitted `admin=1`... :)
|
|
|
|
|
|
|
|
|
|
# good
|
|
|
|
|
User.create(declared(params, include_parent_namespaces: false).to_h)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
>**Note:**
|
|
|
|
|
`declared(params)` return a `Hashie::Mash` object, on which you will have to
|
|
|
|
|
call `.to_h`.
|
|
|
|
|
|
|
|
|
|
But we can use `params[key]` directly when we access single elements.
|
|
|
|
|
|
|
|
|
|
For instance:
|
|
|
|
|
|
|
|
|
|
```ruby
|
|
|
|
|
# good
|
|
|
|
|
Model.create(foo: params[:foo])
|
|
|
|
|
```
|
|
|
|
|
|
2019-12-04 20:38:33 +05:30
|
|
|
|
## Using API path helpers in GitLab Rails codebase
|
|
|
|
|
|
|
|
|
|
Because we support [installing GitLab under a relative URL], one must take this
|
|
|
|
|
into account when using API path helpers generated by Grape. Any such API path
|
|
|
|
|
helper usage must be in wrapped into the `expose_path` helper call.
|
|
|
|
|
|
|
|
|
|
For instance:
|
|
|
|
|
|
|
|
|
|
```haml
|
|
|
|
|
- endpoint = expose_path(api_v4_projects_issues_related_merge_requests_path(id: @project.id, issue_iid: @issue.iid))
|
|
|
|
|
```
|
|
|
|
|
|
2019-12-21 20:55:43 +05:30
|
|
|
|
## Internal API
|
|
|
|
|
|
|
|
|
|
The [internal API](./internal_api.md) is documented for internal use. Please keep it up to date so we know what endpoints
|
|
|
|
|
different components are making use of.
|
|
|
|
|
|
|
|
|
|
[Entity]: https://gitlab.com/gitlab-org/gitlab/blob/master/lib/api/entities.rb
|
2017-08-17 22:00:37 +05:30
|
|
|
|
[validation, and coercion of the parameters]: https://github.com/ruby-grape/grape#parameter-validation-and-coercion
|
2019-12-04 20:38:33 +05:30
|
|
|
|
[installing GitLab under a relative URL]: https://docs.gitlab.com/ee/install/relative_url.html
|