Commit e6b91cc3 authored by Douwe Maan's avatar Douwe Maan

Merge branch '42415-omit-projects-from-get-group-endpoint' into 'master'

Resolve "API: /groups/:name query very slow for groups with many projects"

Closes #42415

See merge request gitlab-org/gitlab-ce!20494
parents c7dd9a6e e6f34523
---
title: Adds with_projects optional parameter to GET /groups/:id API endpoint
merge_request: 20494
author:
type: changed
......@@ -210,6 +210,7 @@ Parameters:
| --------- | ---- | -------- | ----------- |
| `id` | integer/string | yes | The ID or [URL-encoded path of the group](README.md#namespaced-path-encoding) owned by the authenticated user |
| `with_custom_attributes` | boolean | no | Include [custom attributes](custom_attributes.md) in response (admins only) |
| `with_projects` | boolean | no | Include details from projects that belong to the specified group (defaults to `true`). |
```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/groups/4
......@@ -361,6 +362,30 @@ Example response:
}
```
When adding the parameter `with_projects=false`, projects will not be returned.
```bash
curl --header "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" https://gitlab.example.com/api/v4/groups/4?with_projects=false
```
Example response:
```json
{
"id": 4,
"name": "Twitter",
"path": "twitter",
"description": "Aliquid qui quis dignissimos distinctio ut commodi voluptas est.",
"visibility": "public",
"avatar_url": null,
"web_url": "https://gitlab.example.com/groups/twitter",
"request_access_enabled": false,
"full_name": "Twitter",
"full_path": "twitter",
"parent_id": null
}
```
## New group
Creates a new project group. Available only for users who can create groups.
......
......@@ -150,12 +150,13 @@ module API
end
params do
use :with_custom_attributes
optional :with_projects, type: Boolean, default: true, desc: 'Omit project details'
end
get ":id" do
group = find_group!(params[:id])
options = {
with: Entities::GroupDetail,
with: params[:with_projects] ? Entities::GroupDetail : Entities::Group,
current_user: current_user
}
......
......@@ -251,14 +251,22 @@ describe API::Groups do
projects
end
def response_project_ids(json_response, key)
json_response[key].map do |project|
project['id'].to_i
end
end
context 'when unauthenticated' do
it 'returns 404 for a private group' do
get api("/groups/#{group2.id}")
expect(response).to have_gitlab_http_status(404)
end
it 'returns 200 for a public group' do
get api("/groups/#{group1.id}")
expect(response).to have_gitlab_http_status(200)
end
......@@ -268,7 +276,7 @@ describe API::Groups do
get api("/groups/#{public_group.id}")
expect(json_response['projects'].map { |p| p['id'].to_i })
expect(response_project_ids(json_response, 'projects'))
.to contain_exactly(projects[:public].id)
end
......@@ -278,7 +286,7 @@ describe API::Groups do
get api("/groups/#{group1.id}")
expect(json_response['shared_projects'].map { |p| p['id'].to_i })
expect(response_project_ids(json_response, 'shared_projects'))
.to contain_exactly(projects[:public].id)
end
end
......@@ -309,6 +317,17 @@ describe API::Groups do
expect(json_response['shared_projects'][0]['id']).to eq(project.id)
end
it "returns one of user1's groups without projects when with_projects option is set to false" do
project = create(:project, namespace: group2, path: 'Foo')
create(:project_group_link, project: project, group: group1)
get api("/groups/#{group1.id}", user1), with_projects: false
expect(response).to have_gitlab_http_status(200)
expect(json_response['projects']).to be_nil
expect(json_response['shared_projects']).to be_nil
end
it "does not return a non existing group" do
get api("/groups/1328", user1)
......@@ -327,7 +346,7 @@ describe API::Groups do
get api("/groups/#{public_group.id}", user2)
expect(json_response['projects'].map { |p| p['id'].to_i })
expect(response_project_ids(json_response, 'projects'))
.to contain_exactly(projects[:public].id, projects[:internal].id)
end
......@@ -337,7 +356,7 @@ describe API::Groups do
get api("/groups/#{group1.id}", user2)
expect(json_response['shared_projects'].map { |p| p['id'].to_i })
expect(response_project_ids(json_response, 'shared_projects'))
.to contain_exactly(projects[:public].id, projects[:internal].id)
end
end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment