Commit graph

13 commits

Author SHA1 Message Date
Dmitriy Zaporozhets
6b8ad689da
Update grape gem
New version of the gem returns 200 status code on delete with content
instead of 204 so we explicitly set status code to keep existing
behavior

Signed-off-by: Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com>
2017-07-20 16:33:18 +03:00
Grzegorz Bizon
0430b76441 Enable Style/DotPosition Rubocop 👮 2017-06-21 13:48:12 +00:00
Rémy Coutable
63360adeae
Add requirements: { id: %r{[^/]+} } for all projects and groups namespaced API routes
Signed-off-by: Rémy Coutable <remy@rymai.me>
2017-03-16 18:00:24 +01:00
Robert Schilling
74c8669b0a Use the pagination helper in the API 2016-12-04 18:11:19 +01:00
Robert Schilling
76bd09326f Use declared_params helper in API 2016-11-14 15:22:06 +01:00
Rémy Coutable
84b7dd763b Use Grape DSL to document methods and their params
Signed-off-by: Rémy Coutable <remy@rymai.me>
2016-10-05 11:20:27 +02:00
Rémy Coutable
c8b1311934 Fix a few things after the initial improvment to Members::DestroyService
Signed-off-by: Rémy Coutable <remy@rymai.me>
2016-10-03 16:57:48 +02:00
Rémy Coutable
3158f57dba Improve Members::DestroyService
Signed-off-by: Rémy Coutable <remy@rymai.me>
2016-10-03 16:57:48 +02:00
Rémy Coutable
924a6b7d33 New AccessRequestsFinder
Signed-off-by: Rémy Coutable <remy@rymai.me>
2016-09-28 08:46:59 +02:00
Rémy Coutable
b3f0a82f50 New Members::ApproveAccessRequestService
Signed-off-by: Rémy Coutable <remy@rymai.me>
2016-09-22 15:50:47 +02:00
Rémy Coutable
d8dd1c1940 Ensure invitees are not returned in Members API
Signed-off-by: Rémy Coutable <remy@rymai.me>
2016-09-16 17:18:26 +02:00
Rémy Coutable
5010be7766 Improve the performance of the GET /:sources/:id/{access_requests,members} API endpoints
The performance was greatly improved by removing two N+1 queries issues
for each endpoint.

For comparison:

1. `GET /projects/:id/members`

With two N+1 queries issues (one was already fxed in the following
snippet):

```
  ProjectMember Load (0.2ms)  SELECT "members".* FROM "members" WHERE
"members"."source_type" = $1 AND "members"."type" IN ('ProjectMember')
AND "members"."source_id" = $2 AND "members"."source_type" = $3 AND
"members"."type" IN ('ProjectMember') AND "members"."requested_at" IS
NULL  ORDER BY "members"."id" DESC  [["source_type", "Project"],
["source_id", 1], ["source_type", "Project"]]
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" IN
(5, 22, 16, 13)  ORDER BY "users"."id" DESC
  ActiveRecord::SchemaMigration Load (0.2ms)  SELECT
"schema_migrations".* FROM "schema_migrations"
  ProjectMember Load (0.3ms)  SELECT  "members".* FROM "members" WHERE
"members"."source_type" = $1 AND "members"."type" IN ('ProjectMember')
AND "members"."source_id" = $2 AND "members"."source_type" = $3 AND
"members"."type" IN ('ProjectMember') AND "members"."requested_at" IS
NULL AND "members"."user_id" = $4  ORDER BY "members"."id" DESC LIMIT 1
[["source_type", "Project"], ["source_id", 1], ["source_type",
"Project"], ["user_id", 5]]
  ProjectMember Load (0.3ms)  SELECT  "members".* FROM "members" WHERE
"members"."source_type" = $1 AND "members"."type" IN ('ProjectMember')
AND "members"."source_id" = $2 AND "members"."source_type" = $3 AND
"members"."type" IN ('ProjectMember') AND "members"."requested_at" IS
NULL AND "members"."user_id" = $4  ORDER BY "members"."id" DESC LIMIT 1
[["source_type", "Project"], ["source_id", 1], ["source_type",
"Project"], ["user_id", 22]]
  ProjectMember Load (0.3ms)  SELECT  "members".* FROM "members" WHERE
"members"."source_type" = $1 AND "members"."type" IN ('ProjectMember')
AND "members"."source_id" = $2 AND "members"."source_type" = $3 AND
"members"."type" IN ('ProjectMember') AND "members"."requested_at" IS
NULL AND "members"."user_id" = $4  ORDER BY "members"."id" DESC LIMIT 1
[["source_type", "Project"], ["source_id", 1], ["source_type",
"Project"], ["user_id", 16]]
  ProjectMember Load (0.3ms)  SELECT  "members".* FROM "members" WHERE
"members"."source_type" = $1 AND "members"."type" IN ('ProjectMember')
AND "members"."source_id" = $2 AND "members"."source_type" = $3 AND
"members"."type" IN ('ProjectMember') AND "members"."requested_at" IS
NULL AND "members"."user_id" = $4  ORDER BY "members"."id" DESC LIMIT 1
[["source_type", "Project"], ["source_id", 1], ["source_type",
"Project"], ["user_id", 13]]
```

Without the N+1 queries issues:

```
  ProjectMember Load (0.3ms)  SELECT  "members".* FROM "members" WHERE
"members"."source_type" = $1 AND "members"."type" IN ('ProjectMember')
AND "members"."source_id" = $2 AND "members"."source_type" = $3 AND
"members"."type" IN ('ProjectMember') AND "members"."requested_at" IS
NULL  ORDER BY "members"."id" DESC LIMIT 20 OFFSET 0  [["source_type",
"Project"], ["source_id", 1], ["source_type", "Project"]]
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" IN
(5, 22, 16, 13)  ORDER BY "users"."id" DESC
```

2. `GET /projects/:id/access_requests`

With two N+1 queries issues:

```
  ProjectMember Load (0.3ms)  SELECT "members".* FROM "members" WHERE
"members"."source_type" = $1 AND "members"."type" IN ('ProjectMember')
AND "members"."source_id" = $2 AND "members"."source_type" = $3 AND
"members"."type" IN ('ProjectMember') AND ("members"."requested_at" IS
NOT NULL)  ORDER BY "members"."id" DESC  [["source_type", "Project"],
["source_id", 8], ["source_type", "Project"]]
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" =
$1  ORDER BY "users"."id" DESC LIMIT 1  [["id", 24]]
  User Load (0.1ms)  SELECT  "users".* FROM "users" WHERE "users"."id" =
$1  ORDER BY "users"."id" DESC LIMIT 1  [["id", 23]]
  ActiveRecord::SchemaMigration Load (0.2ms)  SELECT
"schema_migrations".* FROM "schema_migrations"
  ProjectMember Load (0.1ms)  SELECT  "members".* FROM "members" WHERE
"members"."source_type" = $1 AND "members"."type" IN ('ProjectMember')
AND "members"."source_id" = $2 AND "members"."source_type" = $3 AND
"members"."type" IN ('ProjectMember') AND ("members"."requested_at" IS
NOT NULL) AND "members"."user_id" = $4  ORDER BY "members"."id" DESC
LIMIT 1  [["source_type", "Project"], ["source_id", 8], ["source_type",
"Project"], ["user_id", 24]]
  ProjectMember Load (0.2ms)  SELECT  "members".* FROM "members" WHERE
"members"."source_type" = $1 AND "members"."type" IN ('ProjectMember')
AND "members"."source_id" = $2 AND "members"."source_type" = $3 AND
"members"."type" IN ('ProjectMember') AND ("members"."requested_at" IS
NOT NULL) AND "members"."user_id" = $4  ORDER BY "members"."id" DESC
LIMIT 1  [["source_type", "Project"], ["source_id", 8], ["source_type",
"Project"], ["user_id", 23]]
```

Without the N+1 queries issues:

```
  ProjectMember Load (0.3ms)  SELECT  "members".* FROM "members" WHERE
"members"."source_type" = $1 AND "members"."type" IN ('ProjectMember')
AND "members"."source_id" = $2 AND "members"."source_type" = $3 AND
"members"."type" IN ('ProjectMember') AND ("members"."requested_at" IS
NOT NULL)  ORDER BY "members"."id" DESC LIMIT 20 OFFSET 0
[["source_type", "Project"], ["source_id", 8], ["source_type",
"Project"]]
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" IN
(24, 23)  ORDER BY "users"."id" DESC
```

Signed-off-by: Rémy Coutable <remy@rymai.me>
2016-08-10 19:07:05 +02:00
Rémy Coutable
29850364ec New AccessRequests API endpoints for Group & Project
Also, mutualize AccessRequests and Members endpoints for Group &
Project.
New API documentation for the AccessRequests endpoints.

Signed-off-by: Rémy Coutable <remy@rymai.me>
2016-08-10 19:07:05 +02:00