From 106dbbfbf3dc3638b15dba70a1110f35b8647659 Mon Sep 17 00:00:00 2001
From: Stan Hu <stanhu@gmail.com>
Date: Mon, 27 Apr 2020 23:20:09 +0000
Subject: [PATCH] Revert "Merge branch 'sh-update-grape-gem' into 'master'"

This reverts merge request !27276
---
 .rubocop.yml                                  | 12 ---
 Gemfile                                       |  4 +-
 Gemfile.lock                                  | 55 +++++-------
 changelogs/unreleased/sh-update-grape-gem.yml |  5 --
 doc/development/api_styleguide.md             |  8 --
 doc/development/ee_features.md                | 12 +--
 ee/lib/api/analytics/code_review_analytics.rb |  2 +-
 .../api/analytics/group_activity_analytics.rb |  2 +-
 ee/lib/api/audit_events.rb                    |  2 +-
 ee/lib/api/composer_packages.rb               |  2 +-
 ee/lib/api/conan_packages.rb                  |  2 +-
 ee/lib/api/dependencies.rb                    |  3 +-
 ee/lib/api/dependency_proxy.rb                |  2 +-
 .../api/elasticsearch_indexed_namespaces.rb   |  2 +-
 ee/lib/api/epic_issues.rb                     |  2 +-
 ee/lib/api/epic_links.rb                      |  2 +-
 ee/lib/api/epics.rb                           |  8 +-
 ee/lib/api/feature_flag_scopes.rb             |  2 +-
 ee/lib/api/feature_flags.rb                   |  2 +-
 ee/lib/api/feature_flags_user_lists.rb        |  2 +-
 ee/lib/api/geo.rb                             |  2 +-
 ee/lib/api/geo_nodes.rb                       |  2 +-
 ee/lib/api/geo_replication.rb                 |  2 +-
 ee/lib/api/group_hooks.rb                     |  2 +-
 ee/lib/api/group_packages.rb                  |  2 +-
 .../helpers/project_approval_rules_helpers.rb | 14 ++--
 ee/lib/api/issue_links.rb                     |  2 +-
 ee/lib/api/ldap.rb                            |  2 +-
 ee/lib/api/ldap_group_links.rb                |  2 +-
 ee/lib/api/license.rb                         |  2 +-
 ee/lib/api/managed_licenses.rb                |  2 +-
 ee/lib/api/maven_packages.rb                  |  2 +-
 ee/lib/api/merge_request_approval_rules.rb    | 12 +--
 ee/lib/api/merge_request_approvals.rb         | 10 +--
 ee/lib/api/merge_trains.rb                    |  2 +-
 ee/lib/api/npm_packages.rb                    |  2 +-
 ee/lib/api/nuget_packages.rb                  |  2 +-
 ee/lib/api/package_files.rb                   |  2 +-
 ee/lib/api/project_aliases.rb                 |  2 +-
 ee/lib/api/project_approval_rules.rb          |  2 +-
 ee/lib/api/project_approval_settings.rb       |  2 +-
 ee/lib/api/project_approvals.rb               |  8 +-
 ee/lib/api/project_mirror.rb                  |  2 +-
 ee/lib/api/project_packages.rb                |  2 +-
 ee/lib/api/project_push_rule.rb               |  2 +-
 ee/lib/api/protected_environments.rb          |  2 +-
 ee/lib/api/pypi_packages.rb                   |  2 +-
 ee/lib/api/scim.rb                            |  2 +-
 ee/lib/api/unleash.rb                         |  2 +-
 ee/lib/api/v3/github.rb                       |  2 +-
 ee/lib/api/visual_review_discussions.rb       |  2 +-
 ee/lib/api/vulnerabilities.rb                 |  2 +-
 ee/lib/api/vulnerability_exports.rb           |  2 +-
 ee/lib/api/vulnerability_findings.rb          |  8 +-
 ee/lib/api/vulnerability_issue_links.rb       |  2 +-
 ee/lib/ee/api/boards.rb                       |  2 +-
 ee/lib/ee/api/group_boards.rb                 |  2 +-
 ee/lib/ee/api/helpers/settings_helpers.rb     |  6 +-
 ee/spec/lib/ee/api/helpers_spec.rb            |  2 +-
 .../api/merge_request_approval_rules_spec.rb  | 34 +++-----
 .../api/merge_request_approvals_spec.rb       | 10 +--
 .../api/project_approval_rules_spec.rb        |  1 -
 .../api/project_approval_settings_spec.rb     |  1 -
 ...ject_approval_rules_api_shared_examples.rb |  7 +-
 lib/api/access_requests.rb                    |  2 +-
 lib/api/admin/sidekiq.rb                      |  2 +-
 lib/api/api.rb                                |  2 +-
 lib/api/api_guard.rb                          | 11 +--
 lib/api/appearance.rb                         |  2 +-
 lib/api/applications.rb                       |  2 +-
 lib/api/avatar.rb                             |  2 +-
 lib/api/award_emoji.rb                        |  2 +-
 lib/api/badges.rb                             |  2 +-
 lib/api/boards.rb                             |  2 +-
 lib/api/branches.rb                           |  2 +-
 lib/api/broadcast_messages.rb                 |  2 +-
 lib/api/commit_statuses.rb                    |  2 +-
 lib/api/commits.rb                            |  2 +-
 lib/api/container_registry_event.rb           |  2 +-
 lib/api/deploy_keys.rb                        |  2 +-
 lib/api/deploy_tokens.rb                      |  6 +-
 lib/api/deployments.rb                        |  2 +-
 lib/api/discussions.rb                        |  2 +-
 lib/api/environments.rb                       |  2 +-
 lib/api/error_tracking.rb                     |  2 +-
 lib/api/events.rb                             |  2 +-
 lib/api/features.rb                           |  2 +-
 lib/api/files.rb                              |  2 +-
 lib/api/group_boards.rb                       |  2 +-
 lib/api/group_clusters.rb                     |  2 +-
 lib/api/group_container_repositories.rb       |  2 +-
 lib/api/group_export.rb                       |  2 +-
 lib/api/group_import.rb                       |  2 +-
 lib/api/group_labels.rb                       |  2 +-
 lib/api/group_milestones.rb                   |  2 +-
 lib/api/group_variables.rb                    |  2 +-
 lib/api/groups.rb                             |  4 +-
 lib/api/helpers/merge_requests_helpers.rb     |  2 +-
 lib/api/helpers/projects_helpers.rb           |  2 +-
 lib/api/import_github.rb                      |  2 +-
 lib/api/internal/base.rb                      |  2 +-
 lib/api/internal/pages.rb                     |  2 +-
 lib/api/issues.rb                             | 10 +--
 lib/api/job_artifacts.rb                      |  2 +-
 lib/api/jobs.rb                               |  2 +-
 lib/api/keys.rb                               |  2 +-
 lib/api/labels.rb                             |  2 +-
 lib/api/lint.rb                               |  2 +-
 lib/api/lsif_data.rb                          |  2 +-
 lib/api/markdown.rb                           |  2 +-
 lib/api/members.rb                            |  6 +-
 lib/api/merge_request_diffs.rb                |  2 +-
 lib/api/merge_requests.rb                     |  8 +-
 lib/api/metrics/dashboard/annotations.rb      |  2 +-
 lib/api/milestone_responses.rb                |  2 +-
 lib/api/namespaces.rb                         |  2 +-
 lib/api/notes.rb                              |  2 +-
 lib/api/notification_settings.rb              |  2 +-
 lib/api/pages.rb                              |  2 +-
 lib/api/pages_domains.rb                      |  2 +-
 lib/api/pagination_params.rb                  |  2 +-
 lib/api/pipeline_schedules.rb                 |  2 +-
 lib/api/pipelines.rb                          |  2 +-
 lib/api/project_clusters.rb                   |  2 +-
 lib/api/project_container_repositories.rb     |  2 +-
 lib/api/project_events.rb                     |  2 +-
 lib/api/project_export.rb                     |  2 +-
 lib/api/project_hooks.rb                      |  2 +-
 lib/api/project_import.rb                     |  2 +-
 lib/api/project_milestones.rb                 |  2 +-
 lib/api/project_snapshots.rb                  |  2 +-
 lib/api/project_snippets.rb                   |  2 +-
 lib/api/project_statistics.rb                 |  2 +-
 lib/api/project_templates.rb                  |  2 +-
 lib/api/projects.rb                           |  4 +-
 lib/api/protected_branches.rb                 |  2 +-
 lib/api/protected_tags.rb                     |  2 +-
 lib/api/release/links.rb                      |  2 +-
 lib/api/releases.rb                           |  2 +-
 lib/api/remote_mirrors.rb                     |  2 +-
 lib/api/repositories.rb                       |  4 +-
 lib/api/resource_label_events.rb              |  2 +-
 lib/api/runner.rb                             |  4 +-
 lib/api/runners.rb                            | 12 +--
 lib/api/search.rb                             |  2 +-
 lib/api/services.rb                           |  2 +-
 lib/api/settings.rb                           | 11 ++-
 lib/api/sidekiq_metrics.rb                    |  2 +-
 lib/api/snippets.rb                           |  2 +-
 lib/api/statistics.rb                         |  2 +-
 lib/api/submodules.rb                         |  2 +-
 lib/api/subscriptions.rb                      |  2 +-
 lib/api/suggestions.rb                        |  2 +-
 lib/api/system_hooks.rb                       |  2 +-
 lib/api/tags.rb                               |  2 +-
 lib/api/templates.rb                          |  2 +-
 lib/api/terraform/state.rb                    |  2 +-
 lib/api/todos.rb                              |  2 +-
 lib/api/triggers.rb                           |  2 +-
 lib/api/user_counts.rb                        |  2 +-
 lib/api/users.rb                              |  2 +-
 .../types/comma_separated_to_array.rb         |  2 +-
 .../types/comma_separated_to_integer_array.rb | 15 ----
 lib/api/validations/types/labels_list.rb      | 24 ++++++
 lib/api/validations/types/safe_file.rb        | 15 ++++
 lib/api/validations/types/workhorse_file.rb   | 13 +--
 lib/api/variables.rb                          |  2 +-
 lib/api/version.rb                            |  2 +-
 lib/api/wikis.rb                              |  4 +-
 rubocop/cop/api/grape_api_instance.rb         | 42 ----------
 rubocop/cop/api/grape_array_missing_coerce.rb | 83 -------------------
 spec/requests/api/settings_spec.rb            | 10 +--
 .../cop/api/grape_api_instance_spec.rb        | 31 -------
 .../api/grape_array_missing_coerce_spec.rb    | 64 --------------
 spec/rubocop/cop/code_reuse/worker_spec.rb    |  2 +-
 175 files changed, 307 insertions(+), 562 deletions(-)
 delete mode 100644 changelogs/unreleased/sh-update-grape-gem.yml
 delete mode 100644 lib/api/validations/types/comma_separated_to_integer_array.rb
 create mode 100644 lib/api/validations/types/labels_list.rb
 create mode 100644 lib/api/validations/types/safe_file.rb
 delete mode 100644 rubocop/cop/api/grape_api_instance.rb
 delete mode 100644 rubocop/cop/api/grape_array_missing_coerce.rb
 delete mode 100644 spec/rubocop/cop/api/grape_api_instance_spec.rb
 delete mode 100644 spec/rubocop/cop/api/grape_array_missing_coerce_spec.rb

diff --git a/.rubocop.yml b/.rubocop.yml
index bd19b80e8b56a..300cfe3d74c16 100644
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -284,18 +284,6 @@ Gitlab/Union:
     - 'spec/**/*'
     - 'ee/spec/**/*'
 
-API/GrapeAPIInstance:
-  Enabled: true
-  Include:
-    - 'lib/**/api/**/*.rb'
-    - 'ee/**/api/**/*.rb'
-
-API/GrapeArrayMissingCoerce:
-  Enabled: true
-  Include:
-    - 'lib/**/api/**/*.rb'
-    - 'ee/**/api/**/*.rb'
-
 Cop/SidekiqOptionsQueue:
   Enabled: true
   Exclude:
diff --git a/Gemfile b/Gemfile
index dbde17da603a2..c6dab495cbd07 100644
--- a/Gemfile
+++ b/Gemfile
@@ -19,7 +19,7 @@ gem 'default_value_for', '~> 3.3.0'
 gem 'pg', '~> 1.1'
 
 gem 'rugged', '~> 0.28'
-gem 'grape-path-helpers', '~> 1.3'
+gem 'grape-path-helpers', '~> 1.2'
 
 gem 'faraday', '~> 0.12'
 gem 'marginalia', '~> 1.8.0'
@@ -82,7 +82,7 @@ gem 'gitlab_omniauth-ldap', '~> 2.1.1', require: 'omniauth-ldap'
 gem 'net-ldap'
 
 # API
-gem 'grape', '~> 1.3.2'
+gem 'grape', '~> 1.1.0'
 gem 'grape-entity', '~> 0.7.1'
 gem 'rack-cors', '~> 1.0.6', require: 'rack/cors'
 
diff --git a/Gemfile.lock b/Gemfile.lock
index 3d6472a284d47..be587ef2b5de3 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -103,6 +103,10 @@ GEM
       aws-sdk-core (= 2.11.374)
     aws-sigv4 (1.1.0)
       aws-eventstream (~> 1.0, >= 1.0.2)
+    axiom-types (0.1.1)
+      descendants_tracker (~> 0.0.4)
+      ice_nine (~> 0.11.0)
+      thread_safe (~> 0.3, >= 0.3.1)
     babosa (1.0.2)
     base32 (0.3.2)
     batch-loader (1.4.0)
@@ -161,6 +165,8 @@ GEM
       nap
       open4 (~> 1.3)
     coderay (1.1.2)
+    coercible (1.0.0)
+      descendants_tracker (~> 0.0.1)
     colored2 (3.1.2)
     commonmarker (0.20.1)
       ruby-enum (~> 0.5)
@@ -216,6 +222,8 @@ GEM
       ruby-statistics (>= 2.1)
       thor (>= 0.19, < 2)
       unicode_plot (>= 0.0.4, < 1.0.0)
+    descendants_tracker (0.0.4)
+      thread_safe (~> 0.3, >= 0.3.1)
     device_detector (1.0.0)
     devise (4.7.1)
       bcrypt (~> 3.0)
@@ -242,28 +250,6 @@ GEM
     doorkeeper-openid_connect (1.6.3)
       doorkeeper (>= 5.0, < 5.2)
       json-jwt (~> 1.6)
-    dry-configurable (0.11.5)
-      concurrent-ruby (~> 1.0)
-      dry-core (~> 0.4, >= 0.4.7)
-      dry-equalizer (~> 0.2)
-    dry-container (0.7.2)
-      concurrent-ruby (~> 1.0)
-      dry-configurable (~> 0.1, >= 0.1.3)
-    dry-core (0.4.9)
-      concurrent-ruby (~> 1.0)
-    dry-equalizer (0.3.0)
-    dry-inflector (0.2.0)
-    dry-logic (1.0.6)
-      concurrent-ruby (~> 1.0)
-      dry-core (~> 0.2)
-      dry-equalizer (~> 0.2)
-    dry-types (1.4.0)
-      concurrent-ruby (~> 1.0)
-      dry-container (~> 0.3)
-      dry-core (~> 0.4, >= 0.4.4)
-      dry-equalizer (~> 0.3)
-      dry-inflector (~> 0.1, >= 0.1.2)
-      dry-logic (~> 1.0, >= 1.0.2)
     ed25519 (1.2.4)
     elasticsearch (6.8.0)
       elasticsearch-api (= 6.8.0)
@@ -453,19 +439,19 @@ GEM
       signet (~> 0.7)
     gpgme (2.0.20)
       mini_portile2 (~> 2.3)
-    grape (1.3.2)
+    grape (1.1.0)
       activesupport
       builder
-      dry-types (>= 1.1)
       mustermann-grape (~> 1.0.0)
       rack (>= 1.3.0)
       rack-accept
+      virtus (>= 1.0.0)
     grape-entity (0.7.1)
       activesupport (>= 4.0)
       multi_json (>= 1.3.2)
-    grape-path-helpers (1.3.0)
+    grape-path-helpers (1.2.0)
       activesupport
-      grape (~> 1.3)
+      grape (~> 1.0)
       rake (~> 12)
     grape_logging (1.8.3)
       grape
@@ -659,10 +645,9 @@ GEM
     multi_xml (0.6.0)
     multipart-post (2.1.1)
     murmurhash3 (0.1.6)
-    mustermann (1.1.1)
-      ruby2_keywords (~> 0.0.1)
-    mustermann-grape (1.0.1)
-      mustermann (>= 1.0.0)
+    mustermann (1.0.3)
+    mustermann-grape (1.0.0)
+      mustermann (~> 1.0.0)
     nakayoshi_fork (0.0.4)
     nap (1.1.0)
     nenv (0.3.0)
@@ -976,7 +961,6 @@ GEM
     ruby-saml (1.7.2)
       nokogiri (>= 1.5.10)
     ruby-statistics (2.1.2)
-    ruby2_keywords (0.0.2)
     ruby_dep (1.5.0)
     ruby_parser (3.13.1)
       sexp_processor (~> 4.9)
@@ -1135,6 +1119,11 @@ GEM
       activerecord (>= 3.0)
       activesupport (>= 3.0)
     version_sorter (2.2.4)
+    virtus (1.0.5)
+      axiom-types (~> 0.1)
+      coercible (~> 1.0)
+      descendants_tracker (~> 0.0, >= 0.0.3)
+      equalizer (~> 0.0, >= 0.0.9)
     vmstat (2.3.0)
     warden (1.2.8)
       rack (>= 2.0.6)
@@ -1265,9 +1254,9 @@ DEPENDENCIES
   google-api-client (~> 0.23)
   google-protobuf (~> 3.8.0)
   gpgme (~> 2.0.19)
-  grape (~> 1.3.2)
+  grape (~> 1.1.0)
   grape-entity (~> 0.7.1)
-  grape-path-helpers (~> 1.3)
+  grape-path-helpers (~> 1.2)
   grape_logging (~> 1.7)
   graphiql-rails (~> 1.4.10)
   graphql (~> 1.10.5)
diff --git a/changelogs/unreleased/sh-update-grape-gem.yml b/changelogs/unreleased/sh-update-grape-gem.yml
deleted file mode 100644
index 4aec45c94291b..0000000000000
--- a/changelogs/unreleased/sh-update-grape-gem.yml
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Upgrade Grape v1.1.0 to v1.3.2
-merge_request: 27276
-author:
-type: other
diff --git a/doc/development/api_styleguide.md b/doc/development/api_styleguide.md
index a9ce1bc066ea3..25c8cbd3fde92 100644
--- a/doc/development/api_styleguide.md
+++ b/doc/development/api_styleguide.md
@@ -98,14 +98,6 @@ For instance:
 Model.create(foo: params[:foo])
 ```
 
-## Array types
-
-With Grape v1.3+, Array types must be defined with a `coerce_with`
-block, or parameters will fail to validate when passed a string from an
-API request. See the [Grape upgrading
-documentation](https://github.com/ruby-grape/grape/blob/master/UPGRADING.md#ensure-that-array-types-have-explicit-coercions)
-for more details.
-
 ## Using HTTP status helpers
 
 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.
diff --git a/doc/development/ee_features.md b/doc/development/ee_features.md
index 1d03e93ab792f..c9fd1b75606d8 100644
--- a/doc/development/ee_features.md
+++ b/doc/development/ee_features.md
@@ -513,12 +513,12 @@ do that, so we'll follow regular object-oriented practices that we define the
 interface first here.
 
 For example, suppose we have a few more optional parameters for EE. We can move the
-parameters out of the `Grape::API::Instance` class to a helper module, so we can inject it
+paramters out of the `Grape::API` class to a helper module, so we can inject it
 before it would be used in the class.
 
 ```ruby
 module API
-  class Projects < Grape::API::Instance
+  class Projects < Grape::API
     helpers Helpers::ProjectsHelpers
   end
 end
@@ -579,7 +579,7 @@ class definition to make it easy and clear:
 
 ```ruby
 module API
-  class JobArtifacts < Grape::API::Instance
+  class JobArtifacts < Grape::API
     # EE::API::JobArtifacts would override the following helpers
     helpers do
       def authorize_download_artifacts!
@@ -623,7 +623,7 @@ route. Something like this:
 
 ```ruby
 module API
-  class MergeRequests < Grape::API::Instance
+  class MergeRequests < Grape::API
     helpers do
       # EE::API::MergeRequests would override the following helpers
       def update_merge_request_ee(merge_request)
@@ -692,7 +692,7 @@ least argument. We would approach this as follows:
 ```ruby
 # api/merge_requests/parameters.rb
 module API
-  class MergeRequests < Grape::API::Instance
+  class MergeRequests < Grape::API
     module Parameters
       def self.update_params_at_least_one_of
         %i[
@@ -708,7 +708,7 @@ API::MergeRequests::Parameters.prepend_if_ee('EE::API::MergeRequests::Parameters
 
 # api/merge_requests.rb
 module API
-  class MergeRequests < Grape::API::Instance
+  class MergeRequests < Grape::API
     params do
       at_least_one_of(*Parameters.update_params_at_least_one_of)
     end
diff --git a/ee/lib/api/analytics/code_review_analytics.rb b/ee/lib/api/analytics/code_review_analytics.rb
index b84291e26be4d..2e87935d51e0f 100644
--- a/ee/lib/api/analytics/code_review_analytics.rb
+++ b/ee/lib/api/analytics/code_review_analytics.rb
@@ -2,7 +2,7 @@
 
 module API
   module Analytics
-    class CodeReviewAnalytics < Grape::API::Instance
+    class CodeReviewAnalytics < Grape::API
       include PaginationParams
 
       helpers ::Gitlab::IssuableMetadata
diff --git a/ee/lib/api/analytics/group_activity_analytics.rb b/ee/lib/api/analytics/group_activity_analytics.rb
index 037f89fadbe39..8d1306b35a1c0 100644
--- a/ee/lib/api/analytics/group_activity_analytics.rb
+++ b/ee/lib/api/analytics/group_activity_analytics.rb
@@ -2,7 +2,7 @@
 
 module API
   module Analytics
-    class GroupActivityAnalytics < Grape::API::Instance
+    class GroupActivityAnalytics < Grape::API
       DESCRIPTION_DETAIL =
         'This feature is gated by the `:group_activity_analytics`'\
         ' feature flag, introduced in GitLab 12.9.'
diff --git a/ee/lib/api/audit_events.rb b/ee/lib/api/audit_events.rb
index 85779cc2bcd39..eee4f2eb5f8b6 100644
--- a/ee/lib/api/audit_events.rb
+++ b/ee/lib/api/audit_events.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class AuditEvents < ::Grape::API::Instance
+  class AuditEvents < ::Grape::API
     include ::API::PaginationParams
 
     before do
diff --git a/ee/lib/api/composer_packages.rb b/ee/lib/api/composer_packages.rb
index afc45df21b94b..d65c0bdb75161 100644
--- a/ee/lib/api/composer_packages.rb
+++ b/ee/lib/api/composer_packages.rb
@@ -2,7 +2,7 @@
 
 # PHP composer support (https://getcomposer.org/)
 module API
-  class ComposerPackages < Grape::API::Instance
+  class ComposerPackages < Grape::API
     helpers ::API::Helpers::PackagesManagerClientsHelpers
     helpers ::API::Helpers::RelatedResourcesHelpers
     helpers ::API::Helpers::Packages::BasicAuthHelpers
diff --git a/ee/lib/api/conan_packages.rb b/ee/lib/api/conan_packages.rb
index bf87cf2e391a4..395a39c9d3802 100644
--- a/ee/lib/api/conan_packages.rb
+++ b/ee/lib/api/conan_packages.rb
@@ -9,7 +9,7 @@
 #
 # Technical debt: https://gitlab.com/gitlab-org/gitlab/issues/35798
 module API
-  class ConanPackages < Grape::API::Instance
+  class ConanPackages < Grape::API
     helpers ::API::Helpers::PackagesManagerClientsHelpers
 
     PACKAGE_REQUIREMENTS = {
diff --git a/ee/lib/api/dependencies.rb b/ee/lib/api/dependencies.rb
index 1f6359ac65b94..f3a11bb1366e3 100644
--- a/ee/lib/api/dependencies.rb
+++ b/ee/lib/api/dependencies.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Dependencies < Grape::API::Instance
+  class Dependencies < Grape::API
     helpers do
       def dependencies_by(params)
         pipeline = ::Security::ReportFetchService.new(user_project, ::Ci::JobArtifact.dependency_list_reports).pipeline
@@ -28,7 +28,6 @@ def dependencies_by(params)
       params do
         optional :package_manager,
                  type: Array[String],
-                 coerce_with: Validations::Types::CommaSeparatedToArray.coerce,
                  desc: "Returns dependencies belonging to specified package managers: #{::Security::DependencyListService::FILTER_PACKAGE_MANAGERS_VALUES.join(', ')}.",
                  values: ::Security::DependencyListService::FILTER_PACKAGE_MANAGERS_VALUES
       end
diff --git a/ee/lib/api/dependency_proxy.rb b/ee/lib/api/dependency_proxy.rb
index d1bc4d2c379b7..9ca425d6c0e08 100644
--- a/ee/lib/api/dependency_proxy.rb
+++ b/ee/lib/api/dependency_proxy.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class DependencyProxy < Grape::API::Instance
+  class DependencyProxy < Grape::API
     helpers ::API::Helpers::PackagesHelpers
 
     helpers do
diff --git a/ee/lib/api/elasticsearch_indexed_namespaces.rb b/ee/lib/api/elasticsearch_indexed_namespaces.rb
index 98934edbff659..a37954919e054 100644
--- a/ee/lib/api/elasticsearch_indexed_namespaces.rb
+++ b/ee/lib/api/elasticsearch_indexed_namespaces.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ElasticsearchIndexedNamespaces < Grape::API::Instance
+  class ElasticsearchIndexedNamespaces < Grape::API
     before { authenticated_as_admin! }
 
     resource :elasticsearch_indexed_namespaces do
diff --git a/ee/lib/api/epic_issues.rb b/ee/lib/api/epic_issues.rb
index 8f91d4818c27d..5e0de5aec9c9d 100644
--- a/ee/lib/api/epic_issues.rb
+++ b/ee/lib/api/epic_issues.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class EpicIssues < Grape::API::Instance
+  class EpicIssues < Grape::API
     before do
       authenticate!
       authorize_epics_feature!
diff --git a/ee/lib/api/epic_links.rb b/ee/lib/api/epic_links.rb
index 08d3f824c77fb..50c725c2e4a61 100644
--- a/ee/lib/api/epic_links.rb
+++ b/ee/lib/api/epic_links.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class EpicLinks < Grape::API::Instance
+  class EpicLinks < Grape::API
     include ::Gitlab::Utils::StrongMemoize
 
     before do
diff --git a/ee/lib/api/epics.rb b/ee/lib/api/epics.rb
index b70492687ee63..5be09b6017796 100644
--- a/ee/lib/api/epics.rb
+++ b/ee/lib/api/epics.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Epics < Grape::API::Instance
+  class Epics < Grape::API
     include PaginationParams
 
     before do
@@ -29,7 +29,7 @@ class Epics < Grape::API::Instance
         optional :state, type: String, values: %w[opened closed all], default: 'all',
                          desc: 'Return opened, closed, or all epics'
         optional :author_id, type: Integer, desc: 'Return epics which are authored by the user with the given ID'
-        optional :labels, type: Array[String], coerce_with: Validations::Types::CommaSeparatedToArray.coerce, desc: 'Comma-separated list of label names'
+        optional :labels, type: Array[String], coerce_with: Validations::Types::LabelsList.coerce, desc: 'Comma-separated list of label names'
         optional :with_labels_details, type: Boolean, desc: 'Return titles of labels and other details', default: false
         optional :created_after, type: DateTime, desc: 'Return epics created after the specified time'
         optional :created_before, type: DateTime, desc: 'Return epics created before the specified time'
@@ -70,7 +70,7 @@ class Epics < Grape::API::Instance
         optional :start_date_is_fixed, type: Boolean, desc: 'Indicates start date should be sourced from start_date_fixed field not the issue milestones'
         optional :end_date, as: :due_date_fixed, type: String, desc: 'The due date of an epic'
         optional :due_date_is_fixed, type: Boolean, desc: 'Indicates due date should be sourced from due_date_fixed field not the issue milestones'
-        optional :labels, type: Array[String], coerce_with: Validations::Types::CommaSeparatedToArray.coerce, desc: 'Comma-separated list of label names'
+        optional :labels, type: Array[String], coerce_with: Validations::Types::LabelsList.coerce, desc: 'Comma-separated list of label names'
         optional :parent_id, type: Integer, desc: 'The id of a parent epic'
       end
       post ':id/(-/)epics' do
@@ -96,7 +96,7 @@ class Epics < Grape::API::Instance
         optional :start_date_is_fixed, type: Boolean, desc: 'Indicates start date should be sourced from start_date_fixed field not the issue milestones'
         optional :end_date, as: :due_date_fixed, type: String, desc: 'The due date of an epic'
         optional :due_date_is_fixed, type: Boolean, desc: 'Indicates due date should be sourced from due_date_fixed field not the issue milestones'
-        optional :labels, type: Array[String], coerce_with: Validations::Types::CommaSeparatedToArray.coerce, desc: 'Comma-separated list of label names'
+        optional :labels, type: Array[String], coerce_with: Validations::Types::LabelsList.coerce, desc: 'Comma-separated list of label names'
         optional :state_event, type: String, values: %w[reopen close], desc: 'State event for an epic'
         at_least_one_of :title, :description, :start_date_fixed, :start_date_is_fixed, :due_date_fixed, :due_date_is_fixed, :labels, :state_event, :confidential
       end
diff --git a/ee/lib/api/feature_flag_scopes.rb b/ee/lib/api/feature_flag_scopes.rb
index 1dd457d848538..d3b59c6ede8c7 100644
--- a/ee/lib/api/feature_flag_scopes.rb
+++ b/ee/lib/api/feature_flag_scopes.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class FeatureFlagScopes < Grape::API::Instance
+  class FeatureFlagScopes < Grape::API
     include PaginationParams
 
     ENVIRONMENT_SCOPE_ENDPOINT_REQUIREMENTS = FeatureFlags::FEATURE_FLAG_ENDPOINT_REQUIREMENTS
diff --git a/ee/lib/api/feature_flags.rb b/ee/lib/api/feature_flags.rb
index c09100b5b5fc2..460527b9da51a 100644
--- a/ee/lib/api/feature_flags.rb
+++ b/ee/lib/api/feature_flags.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class FeatureFlags < Grape::API::Instance
+  class FeatureFlags < Grape::API
     include PaginationParams
 
     FEATURE_FLAG_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS
diff --git a/ee/lib/api/feature_flags_user_lists.rb b/ee/lib/api/feature_flags_user_lists.rb
index 78dbe57e9629e..0bc78bdb04693 100644
--- a/ee/lib/api/feature_flags_user_lists.rb
+++ b/ee/lib/api/feature_flags_user_lists.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class FeatureFlagsUserLists < Grape::API::Instance
+  class FeatureFlagsUserLists < Grape::API
     include PaginationParams
 
     error_formatter :json, -> (message, _backtrace, _options, _env, _original_exception) {
diff --git a/ee/lib/api/geo.rb b/ee/lib/api/geo.rb
index 134414dbaeefc..59cb0984ae284 100644
--- a/ee/lib/api/geo.rb
+++ b/ee/lib/api/geo.rb
@@ -3,7 +3,7 @@
 require 'base64'
 
 module API
-  class Geo < Grape::API::Instance
+  class Geo < Grape::API
     resource :geo do
       helpers do
         def sanitized_node_status_params
diff --git a/ee/lib/api/geo_nodes.rb b/ee/lib/api/geo_nodes.rb
index a49085c3665e8..82089ca28606c 100644
--- a/ee/lib/api/geo_nodes.rb
+++ b/ee/lib/api/geo_nodes.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class GeoNodes < Grape::API::Instance
+  class GeoNodes < Grape::API
     include PaginationParams
     include APIGuard
     include ::Gitlab::Utils::StrongMemoize
diff --git a/ee/lib/api/geo_replication.rb b/ee/lib/api/geo_replication.rb
index a726b6d1b3b0f..212a0219a4c28 100644
--- a/ee/lib/api/geo_replication.rb
+++ b/ee/lib/api/geo_replication.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class GeoReplication < Grape::API::Instance
+  class GeoReplication < Grape::API
     include PaginationParams
     include APIGuard
     include ::Gitlab::Utils::StrongMemoize
diff --git a/ee/lib/api/group_hooks.rb b/ee/lib/api/group_hooks.rb
index 1da1b99242b99..13fbb77d3aea4 100644
--- a/ee/lib/api/group_hooks.rb
+++ b/ee/lib/api/group_hooks.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class GroupHooks < Grape::API::Instance
+  class GroupHooks < Grape::API
     include ::API::PaginationParams
 
     before { authenticate! }
diff --git a/ee/lib/api/group_packages.rb b/ee/lib/api/group_packages.rb
index 0393dcdf9a234..0c1be8abf98a7 100644
--- a/ee/lib/api/group_packages.rb
+++ b/ee/lib/api/group_packages.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class GroupPackages < Grape::API::Instance
+  class GroupPackages < Grape::API
     include PaginationParams
 
     before do
diff --git a/ee/lib/api/helpers/project_approval_rules_helpers.rb b/ee/lib/api/helpers/project_approval_rules_helpers.rb
index a12cb75c60339..3e43e7c27fd7f 100644
--- a/ee/lib/api/helpers/project_approval_rules_helpers.rb
+++ b/ee/lib/api/helpers/project_approval_rules_helpers.rb
@@ -5,22 +5,24 @@ module Helpers
     module ProjectApprovalRulesHelpers
       extend Grape::API::Helpers
 
+      ARRAY_COERCION_LAMBDA = ->(val) { val.empty? ? [] : Array.wrap(val) }
+
       params :create_project_approval_rule do
         requires :name, type: String, desc: 'The name of the approval rule'
         requires :approvals_required, type: Integer, desc: 'The number of required approvals for this rule'
         optional :rule_type, type: String, desc: 'The type of approval rule'
-        optional :users, as: :user_ids, type: Array[Integer], coerce_with: Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The user ids for this rule'
-        optional :groups, as: :group_ids, type: Array[Integer], coerce_with: Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The group ids for this rule'
-        optional :protected_branch_ids, type: Array[Integer], coerce_with: Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The protected branch ids for this rule'
+        optional :users, as: :user_ids, type: Array, coerce_with: ARRAY_COERCION_LAMBDA, desc: 'The user ids for this rule'
+        optional :groups, as: :group_ids, type: Array, coerce_with: ARRAY_COERCION_LAMBDA, desc: 'The group ids for this rule'
+        optional :protected_branch_ids, type: Array, coerce_with: ARRAY_COERCION_LAMBDA, desc: 'The protected branch ids for this rule'
       end
 
       params :update_project_approval_rule do
         requires :approval_rule_id, type: Integer, desc: 'The ID of an approval_rule'
         optional :name, type: String, desc: 'The name of the approval rule'
         optional :approvals_required, type: Integer, desc: 'The number of required approvals for this rule'
-        optional :users, as: :user_ids, type: Array[Integer], coerce_with: Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The user ids for this rule'
-        optional :groups, as: :group_ids, type: Array[Integer], coerce_with: Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The group ids for this rule'
-        optional :protected_branch_ids, type: Array[Integer], coerce_with: Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The protected branch ids for this rule'
+        optional :users, as: :user_ids, type: Array, coerce_with: ARRAY_COERCION_LAMBDA, desc: 'The user ids for this rule'
+        optional :groups, as: :group_ids, type: Array, coerce_with: ARRAY_COERCION_LAMBDA, desc: 'The group ids for this rule'
+        optional :protected_branch_ids, type: Array, coerce_with: ARRAY_COERCION_LAMBDA, desc: 'The protected branch ids for this rule'
         optional :remove_hidden_groups, type: Boolean, desc: 'Whether hidden groups should be removed'
       end
 
diff --git a/ee/lib/api/issue_links.rb b/ee/lib/api/issue_links.rb
index 79a37f0e5e3ce..4769f8ef86576 100644
--- a/ee/lib/api/issue_links.rb
+++ b/ee/lib/api/issue_links.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class IssueLinks < Grape::API::Instance
+  class IssueLinks < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/ee/lib/api/ldap.rb b/ee/lib/api/ldap.rb
index 980fda44e5e8d..2695399b5af55 100644
--- a/ee/lib/api/ldap.rb
+++ b/ee/lib/api/ldap.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Ldap < Grape::API::Instance
+  class Ldap < Grape::API
     # Admin users by default should be able to access these API endpoints.
     # However, non-admin users can access these endpoints if the "Allow group
     # owners to manage LDAP-related group settings" is enabled, and they own a
diff --git a/ee/lib/api/ldap_group_links.rb b/ee/lib/api/ldap_group_links.rb
index 19763a41dc83f..9a82a2c1ff1c1 100644
--- a/ee/lib/api/ldap_group_links.rb
+++ b/ee/lib/api/ldap_group_links.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class LdapGroupLinks < Grape::API::Instance
+  class LdapGroupLinks < Grape::API
     before { authenticate! }
 
     params do
diff --git a/ee/lib/api/license.rb b/ee/lib/api/license.rb
index 1bc234576bc52..0682effccfd1f 100644
--- a/ee/lib/api/license.rb
+++ b/ee/lib/api/license.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class License < Grape::API::Instance
+  class License < Grape::API
     before { authenticated_as_admin! }
 
     resource :license do
diff --git a/ee/lib/api/managed_licenses.rb b/ee/lib/api/managed_licenses.rb
index 899b14bc9ac24..807471382b7fd 100644
--- a/ee/lib/api/managed_licenses.rb
+++ b/ee/lib/api/managed_licenses.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ManagedLicenses < Grape::API::Instance
+  class ManagedLicenses < Grape::API
     include PaginationParams
 
     before { authenticate! unless route.settings[:skip_authentication] }
diff --git a/ee/lib/api/maven_packages.rb b/ee/lib/api/maven_packages.rb
index 069369a4014b1..07d9487e95751 100644
--- a/ee/lib/api/maven_packages.rb
+++ b/ee/lib/api/maven_packages.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 module API
-  class MavenPackages < Grape::API::Instance
+  class MavenPackages < Grape::API
     MAVEN_ENDPOINT_REQUIREMENTS = {
       file_name: API::NO_SLASH_URL_PART_REGEX
     }.freeze
diff --git a/ee/lib/api/merge_request_approval_rules.rb b/ee/lib/api/merge_request_approval_rules.rb
index d314695bfa15e..a959f9a601352 100644
--- a/ee/lib/api/merge_request_approval_rules.rb
+++ b/ee/lib/api/merge_request_approval_rules.rb
@@ -1,9 +1,11 @@
 # frozen_string_literal: true
 
 module API
-  class MergeRequestApprovalRules < ::Grape::API::Instance
+  class MergeRequestApprovalRules < ::Grape::API
     before { authenticate_non_get! }
 
+    ARRAY_COERCION_LAMBDA = ->(val) { val.empty? ? [] : Array.wrap(val) }
+
     helpers do
       def find_merge_request_approval_rule(merge_request, id)
         merge_request.approval_rules.find_by_id!(id)
@@ -32,8 +34,8 @@ def find_merge_request_approval_rule(merge_request, id)
           requires :name, type: String, desc: 'The name of the approval rule'
           requires :approvals_required, type: Integer, desc: 'The number of required approvals for this rule'
           optional :approval_project_rule_id, type: Integer, desc: 'The ID of a project-level approval rule'
-          optional :user_ids, type: Array[Integer], coerce_with: Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The user ids for this rule'
-          optional :group_ids, type: Array[Integer], coerce_with: Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The group ids for this rule'
+          optional :user_ids, type: Array, coerce_with: ARRAY_COERCION_LAMBDA, desc: 'The user ids for this rule'
+          optional :group_ids, type: Array, coerce_with: ARRAY_COERCION_LAMBDA, desc: 'The group ids for this rule'
         end
         post do
           merge_request = find_merge_request_with_access(params[:merge_request_iid], :update_approvers)
@@ -54,8 +56,8 @@ def find_merge_request_approval_rule(merge_request, id)
             requires :approval_rule_id, type: Integer, desc: 'The ID of an approval rule'
             optional :name, type: String, desc: 'The name of the approval rule'
             optional :approvals_required, type: Integer, desc: 'The number of required approvals for this rule'
-            optional :user_ids, type: Array[Integer], coerce_with: Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The user ids for this rule'
-            optional :group_ids, type: Array[Integer], coerce_with: Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The group ids for this rule'
+            optional :user_ids, type: Array, coerce_with: ARRAY_COERCION_LAMBDA, desc: 'The user ids for this rule'
+            optional :group_ids, type: Array, coerce_with: ARRAY_COERCION_LAMBDA, desc: 'The group ids for this rule'
             optional :remove_hidden_groups, type: Boolean, desc: 'Whether hidden groups should be removed'
           end
           put do
diff --git a/ee/lib/api/merge_request_approvals.rb b/ee/lib/api/merge_request_approvals.rb
index a759a25244a43..0d5fe79640146 100644
--- a/ee/lib/api/merge_request_approvals.rb
+++ b/ee/lib/api/merge_request_approvals.rb
@@ -1,9 +1,11 @@
 # frozen_string_literal: true
 
 module API
-  class MergeRequestApprovals < ::Grape::API::Instance
+  class MergeRequestApprovals < ::Grape::API
     before { authenticate_non_get! }
 
+    ARRAY_COERCION_LAMBDA = ->(val) { val.empty? ? [] : Array.wrap(val) }
+
     helpers do
       def present_approval(merge_request)
         present merge_request.approval_state, with: ::EE::API::Entities::ApprovalState, current_user: current_user
@@ -107,10 +109,8 @@ def present_merge_request_approval_state(presenter:, target_branch: nil)
           success ::EE::API::Entities::ApprovalState
         end
         params do
-          requires :approver_ids, type: Array[Integer], coerce_with: Validations::Types::CommaSeparatedToIntegerArray.coerce,
-            desc: 'Array of User IDs to set as approvers.'
-          requires :approver_group_ids, type: Array[Integer], coerce_with: Validations::Types::CommaSeparatedToIntegerArray.coerce,
-            desc: 'Array of Group IDs to set as approvers.'
+          requires :approver_ids, type: Array[String], coerce_with: ARRAY_COERCION_LAMBDA, desc: 'Array of User IDs to set as approvers.'
+          requires :approver_group_ids, type: Array[String], coerce_with: ARRAY_COERCION_LAMBDA, desc: 'Array of Group IDs to set as approvers.'
         end
         put 'approvers' do
           Gitlab::QueryLimiting.whitelist('https://gitlab.com/gitlab-org/gitlab/issues/8883')
diff --git a/ee/lib/api/merge_trains.rb b/ee/lib/api/merge_trains.rb
index 63df464083153..d2122a3a8e588 100644
--- a/ee/lib/api/merge_trains.rb
+++ b/ee/lib/api/merge_trains.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class MergeTrains < ::Grape::API::Instance
+  class MergeTrains < ::Grape::API
     include PaginationParams
 
     before do
diff --git a/ee/lib/api/npm_packages.rb b/ee/lib/api/npm_packages.rb
index 391367d226828..a3150e1f19f3c 100644
--- a/ee/lib/api/npm_packages.rb
+++ b/ee/lib/api/npm_packages.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 module API
-  class NpmPackages < Grape::API::Instance
+  class NpmPackages < Grape::API
     helpers ::API::Helpers::PackagesHelpers
     helpers ::API::Helpers::Packages::DependencyProxyHelpers
 
diff --git a/ee/lib/api/nuget_packages.rb b/ee/lib/api/nuget_packages.rb
index 670bc2cad1cc7..a7413d054addf 100644
--- a/ee/lib/api/nuget_packages.rb
+++ b/ee/lib/api/nuget_packages.rb
@@ -6,7 +6,7 @@
 # called by the NuGet package manager client when users run commands
 # like `nuget install` or `nuget push`.
 module API
-  class NugetPackages < Grape::API::Instance
+  class NugetPackages < Grape::API
     helpers ::API::Helpers::PackagesManagerClientsHelpers
     helpers ::API::Helpers::Packages::BasicAuthHelpers
 
diff --git a/ee/lib/api/package_files.rb b/ee/lib/api/package_files.rb
index 69ba78c55882a..e82a4fa763149 100644
--- a/ee/lib/api/package_files.rb
+++ b/ee/lib/api/package_files.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class PackageFiles < Grape::API::Instance
+  class PackageFiles < Grape::API
     include PaginationParams
 
     before do
diff --git a/ee/lib/api/project_aliases.rb b/ee/lib/api/project_aliases.rb
index fba4fbbca9c30..8e346b4c65839 100644
--- a/ee/lib/api/project_aliases.rb
+++ b/ee/lib/api/project_aliases.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProjectAliases < Grape::API::Instance
+  class ProjectAliases < Grape::API
     include PaginationParams
 
     before { check_feature_availability }
diff --git a/ee/lib/api/project_approval_rules.rb b/ee/lib/api/project_approval_rules.rb
index 1f8ebf442f050..2e7a26870d6fd 100644
--- a/ee/lib/api/project_approval_rules.rb
+++ b/ee/lib/api/project_approval_rules.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProjectApprovalRules < ::Grape::API::Instance
+  class ProjectApprovalRules < ::Grape::API
     before { authenticate! }
 
     helpers ::API::Helpers::ProjectApprovalRulesHelpers
diff --git a/ee/lib/api/project_approval_settings.rb b/ee/lib/api/project_approval_settings.rb
index 30d9d704a3de8..dbd0ccb753b0d 100644
--- a/ee/lib/api/project_approval_settings.rb
+++ b/ee/lib/api/project_approval_settings.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProjectApprovalSettings < ::Grape::API::Instance
+  class ProjectApprovalSettings < ::Grape::API
     before { authenticate! }
 
     helpers ::API::Helpers::ProjectApprovalRulesHelpers
diff --git a/ee/lib/api/project_approvals.rb b/ee/lib/api/project_approvals.rb
index 3aa5f48cc22fc..306f9cc147d0a 100644
--- a/ee/lib/api/project_approvals.rb
+++ b/ee/lib/api/project_approvals.rb
@@ -1,10 +1,12 @@
 # frozen_string_literal: true
 
 module API
-  class ProjectApprovals < ::Grape::API::Instance
+  class ProjectApprovals < ::Grape::API
     before { authenticate! }
     before { authorize! :update_approvers, user_project }
 
+    ARRAY_COERCION_LAMBDA = ->(val) { val.empty? ? [] : Array.wrap(val) }
+
     helpers do
       def filter_forbidden_param!(permission, param)
         unless can?(current_user, permission, user_project)
@@ -65,8 +67,8 @@ def filter_params(params)
         success EE::API::Entities::ApprovalSettings
       end
       params do
-        requires :approver_ids, type: Array[Integer], coerce_with: Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'Array of User IDs to set as approvers.'
-        requires :approver_group_ids, type: Array[Integer], coerce_with: Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'Array of Group IDs to set as approvers.'
+        requires :approver_ids, type: Array[String], coerce_with: ARRAY_COERCION_LAMBDA, desc: 'Array of User IDs to set as approvers.'
+        requires :approver_group_ids, type: Array[String], coerce_with: ARRAY_COERCION_LAMBDA, desc: 'Array of Group IDs to set as approvers.'
       end
       put ':id/approvers' do
         result = ::Projects::UpdateService.new(user_project, current_user, declared(params, include_parent_namespaces: false).merge(remove_old_approvers: true)).execute
diff --git a/ee/lib/api/project_mirror.rb b/ee/lib/api/project_mirror.rb
index 81ea3d0b889fd..14c5d3acca161 100644
--- a/ee/lib/api/project_mirror.rb
+++ b/ee/lib/api/project_mirror.rb
@@ -3,7 +3,7 @@
 require_dependency 'declarative_policy'
 
 module API
-  class ProjectMirror < Grape::API::Instance
+  class ProjectMirror < Grape::API
     helpers do
       def github_webhook_signature
         @github_webhook_signature ||= headers['X-Hub-Signature']
diff --git a/ee/lib/api/project_packages.rb b/ee/lib/api/project_packages.rb
index 0c25c70935a60..e7d8617afeb50 100644
--- a/ee/lib/api/project_packages.rb
+++ b/ee/lib/api/project_packages.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProjectPackages < Grape::API::Instance
+  class ProjectPackages < Grape::API
     include PaginationParams
 
     before do
diff --git a/ee/lib/api/project_push_rule.rb b/ee/lib/api/project_push_rule.rb
index 7a3cc1dba7d81..ed66fce5977cf 100644
--- a/ee/lib/api/project_push_rule.rb
+++ b/ee/lib/api/project_push_rule.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProjectPushRule < Grape::API::Instance
+  class ProjectPushRule < Grape::API
     before { authenticate! }
     before { authorize_admin_project }
     before { check_project_feature_available!(:push_rules) }
diff --git a/ee/lib/api/protected_environments.rb b/ee/lib/api/protected_environments.rb
index 6de0ce19d9183..23c92ed7391c0 100644
--- a/ee/lib/api/protected_environments.rb
+++ b/ee/lib/api/protected_environments.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProtectedEnvironments < Grape::API::Instance
+  class ProtectedEnvironments < Grape::API
     include PaginationParams
 
     ENVIRONMENT_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(name: API::NO_SLASH_URL_PART_REGEX)
diff --git a/ee/lib/api/pypi_packages.rb b/ee/lib/api/pypi_packages.rb
index 1dc8a569cce1b..12be25ac7cdde 100644
--- a/ee/lib/api/pypi_packages.rb
+++ b/ee/lib/api/pypi_packages.rb
@@ -6,7 +6,7 @@
 # called by the PyPI package manager client when users run commands
 # like `pip install` or `twine upload`.
 module API
-  class PypiPackages < Grape::API::Instance
+  class PypiPackages < Grape::API
     helpers ::API::Helpers::PackagesManagerClientsHelpers
     helpers ::API::Helpers::RelatedResourcesHelpers
     helpers ::API::Helpers::Packages::BasicAuthHelpers
diff --git a/ee/lib/api/scim.rb b/ee/lib/api/scim.rb
index 102cd47818100..8590fe7e3899a 100644
--- a/ee/lib/api/scim.rb
+++ b/ee/lib/api/scim.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Scim < Grape::API::Instance
+  class Scim < Grape::API
     include ::Gitlab::Utils::StrongMemoize
 
     prefix 'api/scim'
diff --git a/ee/lib/api/unleash.rb b/ee/lib/api/unleash.rb
index 4adb693b5681f..878ee0aa0ff09 100644
--- a/ee/lib/api/unleash.rb
+++ b/ee/lib/api/unleash.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Unleash < Grape::API::Instance
+  class Unleash < Grape::API
     include PaginationParams
 
     namespace :feature_flags do
diff --git a/ee/lib/api/v3/github.rb b/ee/lib/api/v3/github.rb
index c477cbb663e7c..2fe5ef45f7ff7 100644
--- a/ee/lib/api/v3/github.rb
+++ b/ee/lib/api/v3/github.rb
@@ -7,7 +7,7 @@
 #
 module API
   module V3
-    class Github < Grape::API::Instance
+    class Github < Grape::API
       JIRA_DEV_PANEL_FEATURE = :jira_dev_panel_integration.freeze
       NO_SLASH_URL_PART_REGEX = %r{[^/]+}.freeze
       ENDPOINT_REQUIREMENTS = {
diff --git a/ee/lib/api/visual_review_discussions.rb b/ee/lib/api/visual_review_discussions.rb
index 86fdf3342271c..76ae44fa4052d 100644
--- a/ee/lib/api/visual_review_discussions.rb
+++ b/ee/lib/api/visual_review_discussions.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class VisualReviewDiscussions < Grape::API::Instance
+  class VisualReviewDiscussions < Grape::API
     include PaginationParams
     helpers ::API::Helpers::NotesHelpers
     helpers ::RendersNotes
diff --git a/ee/lib/api/vulnerabilities.rb b/ee/lib/api/vulnerabilities.rb
index 60e1ca10a2f1a..7f204735a3dcc 100644
--- a/ee/lib/api/vulnerabilities.rb
+++ b/ee/lib/api/vulnerabilities.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Vulnerabilities < Grape::API::Instance
+  class Vulnerabilities < Grape::API
     include ::API::Helpers::VulnerabilitiesHooks
     include PaginationParams
 
diff --git a/ee/lib/api/vulnerability_exports.rb b/ee/lib/api/vulnerability_exports.rb
index de9d7169dc0e2..38256a87abdfd 100644
--- a/ee/lib/api/vulnerability_exports.rb
+++ b/ee/lib/api/vulnerability_exports.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class VulnerabilityExports < Grape::API::Instance
+  class VulnerabilityExports < Grape::API
     include ::API::Helpers::VulnerabilitiesHooks
     include ::Gitlab::Utils::StrongMemoize
 
diff --git a/ee/lib/api/vulnerability_findings.rb b/ee/lib/api/vulnerability_findings.rb
index c44655419885b..611ad21f077eb 100644
--- a/ee/lib/api/vulnerability_findings.rb
+++ b/ee/lib/api/vulnerability_findings.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class VulnerabilityFindings < Grape::API::Instance
+  class VulnerabilityFindings < Grape::API
     include PaginationParams
     include ::Gitlab::Utils::StrongMemoize
 
@@ -33,23 +33,19 @@ def vulnerability_occurrences_by(params)
     end
     resource :projects, requirements: API::NAMESPACE_OR_PROJECT_REQUIREMENTS do
       params do
-        optional :report_type, type: Array[String],
-                 coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce,
-                 desc: 'The type of report vulnerability belongs to',
+        optional :report_type, type: Array[String], desc: 'The type of report vulnerability belongs to',
                  values: ::Vulnerabilities::Occurrence.report_types.keys,
                  default: ::Vulnerabilities::Occurrence.report_types.keys
         optional :scope, type: String, desc: 'Return vulnerabilities for the given scope: `dismissed` or `all`',
                  default: 'dismissed', values: %w[all dismissed]
         optional :severity,
                  type: Array[String],
-                 coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce,
                  desc: 'Returns vulnerabilities belonging to specified severity level: '\
                        '`info`, `unknown`, `low`, `medium`, `high`, or `critical`. Defaults to all',
                  values: ::Vulnerabilities::Occurrence.severities.keys,
                  default: ::Vulnerabilities::Occurrence.severities.keys
         optional :confidence,
                  type: Array[String],
-                 coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce,
                  desc: 'Returns vulnerabilities belonging to specified confidence level: '\
                        '`undefined`, `ignore`, `unknown`, `experimental`, `low`, `medium`, `high`, or `confirmed`. '\
                        'Defaults to all',
diff --git a/ee/lib/api/vulnerability_issue_links.rb b/ee/lib/api/vulnerability_issue_links.rb
index 59b0458fd98ac..ddcd99ece1fd9 100644
--- a/ee/lib/api/vulnerability_issue_links.rb
+++ b/ee/lib/api/vulnerability_issue_links.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class VulnerabilityIssueLinks < Grape::API::Instance
+  class VulnerabilityIssueLinks < Grape::API
     include ::API::Helpers::VulnerabilitiesHooks
 
     helpers ::API::Helpers::VulnerabilitiesHelpers
diff --git a/ee/lib/ee/api/boards.rb b/ee/lib/ee/api/boards.rb
index 60495ea870183..6b62a086960a7 100644
--- a/ee/lib/ee/api/boards.rb
+++ b/ee/lib/ee/api/boards.rb
@@ -2,7 +2,7 @@
 
 module EE
   module API
-    class Boards < ::Grape::API::Instance
+    class Boards < ::Grape::API
       include ::API::PaginationParams
       include ::API::BoardsResponses
 
diff --git a/ee/lib/ee/api/group_boards.rb b/ee/lib/ee/api/group_boards.rb
index 44c5ba107ff00..1206fda0383fe 100644
--- a/ee/lib/ee/api/group_boards.rb
+++ b/ee/lib/ee/api/group_boards.rb
@@ -2,7 +2,7 @@
 
 module EE
   module API
-    class GroupBoards < ::Grape::API::Instance
+    class GroupBoards < ::Grape::API
       include ::API::PaginationParams
       include ::API::BoardsResponses
 
diff --git a/ee/lib/ee/api/helpers/settings_helpers.rb b/ee/lib/ee/api/helpers/settings_helpers.rb
index 625748cbfdf1c..1857c56cee3f6 100644
--- a/ee/lib/ee/api/helpers/settings_helpers.rb
+++ b/ee/lib/ee/api/helpers/settings_helpers.rb
@@ -25,8 +25,8 @@ module SettingsHelpers
             end
 
             given elasticsearch_limit_indexing: ->(val) { val } do
-              optional :elasticsearch_namespace_ids, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The namespace ids to index with Elasticsearch.'
-              optional :elasticsearch_project_ids, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The project ids to index with Elasticsearch.'
+              optional :elasticsearch_namespace_ids, type: Array[Integer], coerce_with: ::API::Validations::Types::LabelsList.coerce, desc: 'The namespace ids to index with Elasticsearch.'
+              optional :elasticsearch_project_ids, type: Array[Integer], coerce_with: ::API::Validations::Types::LabelsList.coerce, desc: 'The project ids to index with Elasticsearch.'
             end
 
             optional :email_additional_text, type: String, desc: 'Additional text added to the bottom of every email for legal/auditing/compliance reasons'
@@ -35,7 +35,7 @@ module SettingsHelpers
             optional :help_text, type: String, desc: 'GitLab server administrator information'
             optional :repository_size_limit, type: Integer, desc: 'Size limit per repository (MB)'
             optional :file_template_project_id, type: Integer, desc: 'ID of project where instance-level file templates are stored.'
-            optional :repository_storages, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'A list of names of enabled storage paths, taken from `gitlab.yml`. New projects will be created in one of these stores, chosen at random.'
+            optional :repository_storages, type: Array[String], desc: 'A list of names of enabled storage paths, taken from `gitlab.yml`. New projects will be created in one of these stores, chosen at random.'
             optional :usage_ping_enabled, type: Grape::API::Boolean, desc: 'Every week GitLab will report license usage back to GitLab, Inc.'
             optional :updating_name_disabled_for_users, type: Grape::API::Boolean, desc: 'Flag indicating if users are permitted to update their profile name'
             optional :disable_overriding_approvers_per_merge_request, type: Grape::API::Boolean, desc: 'Disable Users ability to overwrite approvers in merge requests.'
diff --git a/ee/spec/lib/ee/api/helpers_spec.rb b/ee/spec/lib/ee/api/helpers_spec.rb
index ed7ab18c86985..61e57effd59ac 100644
--- a/ee/spec/lib/ee/api/helpers_spec.rb
+++ b/ee/spec/lib/ee/api/helpers_spec.rb
@@ -6,7 +6,7 @@
   include Rack::Test::Methods
 
   let(:helper) do
-    Class.new(Grape::API::Instance) do
+    Class.new(Grape::API) do
       helpers EE::API::Helpers
       helpers API::APIGuard::HelperMethods
       helpers API::Helpers
diff --git a/ee/spec/requests/api/merge_request_approval_rules_spec.rb b/ee/spec/requests/api/merge_request_approval_rules_spec.rb
index 49b69ae8fe990..5f9c4014bb2ef 100644
--- a/ee/spec/requests/api/merge_request_approval_rules_spec.rb
+++ b/ee/spec/requests/api/merge_request_approval_rules_spec.rb
@@ -143,9 +143,7 @@
     let(:current_user) { user }
     let(:url) { "/projects/#{project.id}/merge_requests/#{merge_request.iid}/approval_rules" }
     let(:approver) { create(:user) }
-    let(:other_approver) { create(:user) }
     let(:group) { create(:group) }
-    let(:other_group) { create(:group) }
     let(:approval_project_rule_id) { nil }
     let(:user_ids) { [] }
     let(:group_ids) { [] }
@@ -168,9 +166,7 @@
       before do
         project.update!(disable_overriding_approvers_per_merge_request: false)
         project.add_developer(approver)
-        project.add_developer(other_approver)
         group.add_developer(approver)
-        other_group.add_developer(other_approver)
 
         action
       end
@@ -183,7 +179,7 @@
 
         expect(rule['name']).to eq(params[:name])
         expect(rule['approvals_required']).to eq(params[:approvals_required])
-        expect(rule['rule_type']).to eq('any_approver')
+        expect(rule['rule_type']).to eq('regular')
         expect(rule['contains_hidden_groups']).to eq(false)
         expect(rule['source_rule']).to be_nil
         expect(rule['eligible_approvers']).to be_empty
@@ -192,24 +188,24 @@
       end
 
       context 'users are passed' do
-        let(:user_ids) { "#{approver.id},#{other_approver.id}" }
+        let(:user_ids) { [approver.id] }
 
         it 'includes users' do
           rule = json_response
 
-          expect(rule['eligible_approvers'].map { |approver| approver['id'] }).to contain_exactly(approver.id, other_approver.id)
-          expect(rule['users'].map { |user| user['id'] }).to contain_exactly(approver.id, other_approver.id)
+          expect(rule['eligible_approvers']).to match([hash_including('id' => approver.id)])
+          expect(rule['users']).to match([hash_including('id' => approver.id)])
         end
       end
 
       context 'groups are passed' do
-        let(:group_ids) { "#{group.id},#{other_group.id}" }
+        let(:group_ids) { [group.id] }
 
         it 'includes groups' do
           rule = json_response
 
-          expect(rule['eligible_approvers'].map { |approver| approver['id'] }).to contain_exactly(approver.id, other_approver.id)
-          expect(rule['groups'].map { |group| group['id'] }).to contain_exactly(group.id, other_group.id)
+          expect(rule['eligible_approvers']).to match([hash_including('id' => approver.id)])
+          expect(rule['groups']).to match([hash_including('id' => group.id)])
         end
       end
 
@@ -261,8 +257,6 @@
     let(:user_ids) { [] }
     let(:group_ids) { [] }
     let(:remove_hidden_groups) { nil }
-    let(:other_approver) { create(:user) }
-    let(:other_group) { create(:group) }
 
     let(:params) do
       {
@@ -283,10 +277,8 @@
         project.update!(disable_overriding_approvers_per_merge_request: false)
         project.add_developer(existing_approver)
         project.add_developer(new_approver)
-        project.add_developer(other_approver)
         existing_group.add_developer(existing_approver)
         new_group.add_developer(new_approver)
-        other_group.add_developer(other_approver)
 
         action
       end
@@ -310,24 +302,24 @@
       end
 
       context 'users are passed' do
-        let(:user_ids) { "#{new_approver.id},#{existing_approver.id}" }
+        let(:user_ids) { [new_approver.id] }
 
         it 'changes users' do
           rule = json_response
 
-          expect(rule['eligible_approvers'].map { |approver| approver['id'] }).to contain_exactly(new_approver.id, existing_approver.id)
-          expect(rule['users'].map { |user| user['id'] }).to contain_exactly(new_approver.id, existing_approver.id)
+          expect(rule['eligible_approvers']).to match([hash_including('id' => new_approver.id)])
+          expect(rule['users']).to match([hash_including('id' => new_approver.id)])
         end
       end
 
       context 'groups are passed' do
-        let(:group_ids) { "#{new_group.id},#{other_group.id}" }
+        let(:group_ids) { [new_group.id] }
 
         it 'changes groups' do
           rule = json_response
 
-          expect(rule['eligible_approvers'].map { |approver| approver['id'] }).to contain_exactly(new_approver.id, other_approver.id)
-          expect(rule['groups'].map { |group| group['id'] }).to contain_exactly(new_group.id, other_group.id)
+          expect(rule['eligible_approvers']).to match([hash_including('id' => new_approver.id)])
+          expect(rule['groups']).to match([hash_including('id' => new_group.id)])
         end
       end
 
diff --git a/ee/spec/requests/api/merge_request_approvals_spec.rb b/ee/spec/requests/api/merge_request_approvals_spec.rb
index ac37240afe5ba..d96348d5b987e 100644
--- a/ee/spec/requests/api/merge_request_approvals_spec.rb
+++ b/ee/spec/requests/api/merge_request_approvals_spec.rb
@@ -321,7 +321,7 @@
         it 'does not allow overriding approvers' do
           expect do
             put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/approvers", current_user),
-              params: { approver_ids: approver.id.to_s, approver_group_ids: group.id.to_s }
+              params: { approver_ids: [approver.id], approver_group_ids: [group.id] }
           end.to not_change { merge_request.approvers.count }.and not_change { merge_request.approver_groups.count }
         end
       end
@@ -334,12 +334,12 @@
         it 'allows overriding approvers' do
           expect do
             put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/approvers", current_user),
-              params: { approver_ids: "#{approver.id},#{user2.id}", approver_group_ids: "#{group.id}" }
-          end.to change { merge_request.approvers.count }.from(0).to(2)
+              params: { approver_ids: [approver.id], approver_group_ids: [group.id] }
+          end.to change { merge_request.approvers.count }.from(0).to(1)
             .and change { merge_request.approver_groups.count }.from(0).to(1)
 
           expect(response).to have_gitlab_http_status(:ok)
-          expect(json_response['approvers'].map { |approver| approver['user'] }.map { |user| user['username'] }).to contain_exactly(approver.username, user2.username)
+          expect(json_response['approvers'][0]['user']['username']).to eq(approver.username)
           expect(json_response['approver_groups'][0]['group']['name']).to eq(group.name)
         end
 
@@ -349,7 +349,7 @@
 
           expect do
             put api("/projects/#{project.id}/merge_requests/#{merge_request.iid}/approvers", current_user),
-              params: { approver_ids: '', approver_group_ids: '' }.to_json, headers: { CONTENT_TYPE: 'application/json' }
+              params: { approver_ids: [], approver_group_ids: [] }.to_json, headers: { CONTENT_TYPE: 'application/json' }
           end.to change { merge_request.approvers.count }.from(1).to(0)
             .and change { merge_request.approver_groups.count }.from(1).to(0)
 
diff --git a/ee/spec/requests/api/project_approval_rules_spec.rb b/ee/spec/requests/api/project_approval_rules_spec.rb
index 952e227ab7789..c7e3ad79ed39c 100644
--- a/ee/spec/requests/api/project_approval_rules_spec.rb
+++ b/ee/spec/requests/api/project_approval_rules_spec.rb
@@ -9,7 +9,6 @@
   let_it_be(:admin) { create(:user, :admin) }
   let_it_be(:project) { create(:project, :public, :repository, creator: user, namespace: user.namespace, only_allow_merge_if_pipeline_succeeds: false) }
   let_it_be(:approver) { create(:user) }
-  let_it_be(:other_approver) { create(:user) }
 
   describe 'GET /projects/:id/approval_rules' do
     let(:url) { "/projects/#{project.id}/approval_rules" }
diff --git a/ee/spec/requests/api/project_approval_settings_spec.rb b/ee/spec/requests/api/project_approval_settings_spec.rb
index 69547fcacdf47..be100fa9dac1a 100644
--- a/ee/spec/requests/api/project_approval_settings_spec.rb
+++ b/ee/spec/requests/api/project_approval_settings_spec.rb
@@ -9,7 +9,6 @@
   let_it_be(:admin) { create(:user, :admin) }
   let_it_be(:project) { create(:project, :public, :repository, creator: user, namespace: user.namespace, only_allow_merge_if_pipeline_succeeds: false) }
   let_it_be(:approver) { create(:user) }
-  let_it_be(:other_approver) { create(:user) }
 
   describe 'GET /projects/:id/approval_settings' do
     let(:url) { "/projects/#{project.id}/approval_settings" }
diff --git a/ee/spec/support/shared_examples/requests/api/project_approval_rules_api_shared_examples.rb b/ee/spec/support/shared_examples/requests/api/project_approval_rules_api_shared_examples.rb
index c791ffa541f55..44bc93a57dd18 100644
--- a/ee/spec/support/shared_examples/requests/api/project_approval_rules_api_shared_examples.rb
+++ b/ee/spec/support/shared_examples/requests/api/project_approval_rules_api_shared_examples.rb
@@ -79,7 +79,6 @@
   shared_examples 'a user with access' do
     before do
       project.add_developer(approver)
-      project.add_developer(other_approver)
     end
 
     context 'when protected_branch_ids param is present' do
@@ -118,10 +117,10 @@
 
     it 'sets approvers' do
       expect do
-        put api(url, current_user), params: { users: "#{approver.id},#{other_approver.id}" }
-      end.to change { approval_rule.users.count }.from(0).to(2)
+        put api(url, current_user), params: { users: [approver.id] }
+      end.to change { approval_rule.users.count }.from(0).to(1)
 
-      expect(approval_rule.users).to contain_exactly(approver, other_approver)
+      expect(approval_rule.users).to contain_exactly(approver)
       expect(approval_rule.groups).to be_empty
 
       expect(response).to have_gitlab_http_status(:ok)
diff --git a/lib/api/access_requests.rb b/lib/api/access_requests.rb
index 5305b25538f89..ee8dc822098c2 100644
--- a/lib/api/access_requests.rb
+++ b/lib/api/access_requests.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class AccessRequests < Grape::API::Instance
+  class AccessRequests < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/lib/api/admin/sidekiq.rb b/lib/api/admin/sidekiq.rb
index f4c84f2eee80a..a700bea0fd79d 100644
--- a/lib/api/admin/sidekiq.rb
+++ b/lib/api/admin/sidekiq.rb
@@ -2,7 +2,7 @@
 
 module API
   module Admin
-    class Sidekiq < Grape::API::Instance
+    class Sidekiq < Grape::API
       before { authenticated_as_admin! }
 
       namespace 'admin' do
diff --git a/lib/api/api.rb b/lib/api/api.rb
index 6019a8991f385..de9a3120d9026 100644
--- a/lib/api/api.rb
+++ b/lib/api/api.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class API < Grape::API::Instance
+  class API < Grape::API
     include APIGuard
 
     LOG_FILENAME = Rails.root.join("log", "api_json.log")
diff --git a/lib/api/api_guard.rb b/lib/api/api_guard.rb
index cb83d22a07f1e..9dd2de5c7ba3e 100644
--- a/lib/api/api_guard.rb
+++ b/lib/api/api_guard.rb
@@ -148,16 +148,7 @@ def oauth2_bearer_token_error_handler
                 { scope: e.scopes })
             end
 
-          finished_response = nil
-          response.finish do |rack_response|
-            # Grape expects a Rack::Response
-            # (https://github.com/ruby-grape/grape/commit/c117bff7d22971675f4b34367d3a98bc31c8fc02),
-            # and we need to retrieve it here:
-            # https://github.com/nov/rack-oauth2/blob/40c9a99fd80486ccb8de0e4869ae384547c0d703/lib/rack/oauth2/server/abstract/error.rb#L28
-            finished_response = rack_response
-          end
-
-          finished_response
+          response.finish
         end
       end
     end
diff --git a/lib/api/appearance.rb b/lib/api/appearance.rb
index 8a46ebf4ef4a6..a775102e87d8c 100644
--- a/lib/api/appearance.rb
+++ b/lib/api/appearance.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Appearance < Grape::API::Instance
+  class Appearance < Grape::API
     before { authenticated_as_admin! }
 
     helpers do
diff --git a/lib/api/applications.rb b/lib/api/applications.rb
index 4e8d68c8d094c..70e6b8395d767 100644
--- a/lib/api/applications.rb
+++ b/lib/api/applications.rb
@@ -2,7 +2,7 @@
 
 module API
   # External applications API
-  class Applications < Grape::API::Instance
+  class Applications < Grape::API
     before { authenticated_as_admin! }
 
     resource :applications do
diff --git a/lib/api/avatar.rb b/lib/api/avatar.rb
index 9501e777fffec..0f14d00306592 100644
--- a/lib/api/avatar.rb
+++ b/lib/api/avatar.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Avatar < Grape::API::Instance
+  class Avatar < Grape::API
     resource :avatar do
       desc 'Return avatar url for a user' do
         success Entities::Avatar
diff --git a/lib/api/award_emoji.rb b/lib/api/award_emoji.rb
index 0a3df3ed96edc..8e3b3ff8ce5ef 100644
--- a/lib/api/award_emoji.rb
+++ b/lib/api/award_emoji.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class AwardEmoji < Grape::API::Instance
+  class AwardEmoji < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/lib/api/badges.rb b/lib/api/badges.rb
index f6cd3f83ff386..d2152fad07baa 100644
--- a/lib/api/badges.rb
+++ b/lib/api/badges.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Badges < Grape::API::Instance
+  class Badges < Grape::API
     include PaginationParams
 
     before { authenticate_non_get! }
diff --git a/lib/api/boards.rb b/lib/api/boards.rb
index 1f5086127a81c..87818903705fd 100644
--- a/lib/api/boards.rb
+++ b/lib/api/boards.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Boards < Grape::API::Instance
+  class Boards < Grape::API
     include BoardsResponses
     include PaginationParams
 
diff --git a/lib/api/branches.rb b/lib/api/branches.rb
index 4c8e4b7a11641..999bf1627c187 100644
--- a/lib/api/branches.rb
+++ b/lib/api/branches.rb
@@ -3,7 +3,7 @@
 require 'mime/types'
 
 module API
-  class Branches < Grape::API::Instance
+  class Branches < Grape::API
     include PaginationParams
 
     BRANCH_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(branch: API::NO_SLASH_URL_PART_REGEX)
diff --git a/lib/api/broadcast_messages.rb b/lib/api/broadcast_messages.rb
index dcf950d7a035b..42e7dc751f08f 100644
--- a/lib/api/broadcast_messages.rb
+++ b/lib/api/broadcast_messages.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class BroadcastMessages < Grape::API::Instance
+  class BroadcastMessages < Grape::API
     include PaginationParams
 
     resource :broadcast_messages do
diff --git a/lib/api/commit_statuses.rb b/lib/api/commit_statuses.rb
index a34ac5b0169e2..b4c5d7869a224 100644
--- a/lib/api/commit_statuses.rb
+++ b/lib/api/commit_statuses.rb
@@ -3,7 +3,7 @@
 require 'mime/types'
 
 module API
-  class CommitStatuses < Grape::API::Instance
+  class CommitStatuses < Grape::API
     params do
       requires :id, type: String, desc: 'The ID of a project'
     end
diff --git a/lib/api/commits.rb b/lib/api/commits.rb
index 1a0fe393753dc..086a1b7c40247 100644
--- a/lib/api/commits.rb
+++ b/lib/api/commits.rb
@@ -3,7 +3,7 @@
 require 'mime/types'
 
 module API
-  class Commits < Grape::API::Instance
+  class Commits < Grape::API
     include PaginationParams
 
     before do
diff --git a/lib/api/container_registry_event.rb b/lib/api/container_registry_event.rb
index 0b7c35cadbd4a..6d93cc6533613 100644
--- a/lib/api/container_registry_event.rb
+++ b/lib/api/container_registry_event.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ContainerRegistryEvent < Grape::API::Instance
+  class ContainerRegistryEvent < Grape::API
     DOCKER_DISTRIBUTION_EVENTS_V1_JSON = 'application/vnd.docker.distribution.events.v1+json'
 
     before { authenticate_registry_notification! }
diff --git a/lib/api/deploy_keys.rb b/lib/api/deploy_keys.rb
index def479ba99b0f..e86bcc19b2b07 100644
--- a/lib/api/deploy_keys.rb
+++ b/lib/api/deploy_keys.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class DeployKeys < Grape::API::Instance
+  class DeployKeys < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/lib/api/deploy_tokens.rb b/lib/api/deploy_tokens.rb
index c088c71cde7a5..f3a08ae970ada 100644
--- a/lib/api/deploy_tokens.rb
+++ b/lib/api/deploy_tokens.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class DeployTokens < Grape::API::Instance
+  class DeployTokens < Grape::API
     include PaginationParams
 
     helpers do
@@ -54,7 +54,7 @@ def scope_params
 
       params do
         requires :name, type: String, desc: "New deploy token's name"
-        requires :scopes, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, values: ::DeployToken::AVAILABLE_SCOPES.map(&:to_s),
+        requires :scopes, type: Array[String], values: ::DeployToken::AVAILABLE_SCOPES.map(&:to_s),
           desc: 'Indicates the deploy token scopes. Must be at least one of "read_repository", "read_registry", or "write_registry".'
         optional :expires_at, type: DateTime, desc: 'Expiration date for the deploy token. Does not expire if no value is provided.'
         optional :username, type: String, desc: 'Username for deploy token. Default is `gitlab+deploy-token-{n}`'
@@ -117,7 +117,7 @@ def scope_params
 
       params do
         requires :name, type: String, desc: 'The name of the deploy token'
-        requires :scopes, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, values: ::DeployToken::AVAILABLE_SCOPES.map(&:to_s),
+        requires :scopes, type: Array[String], values: ::DeployToken::AVAILABLE_SCOPES.map(&:to_s),
           desc: 'Indicates the deploy token scopes. Must be at least one of "read_repository", "read_registry", or "write_registry".'
         optional :expires_at, type: DateTime, desc: 'Expiration date for the deploy token. Does not expire if no value is provided.'
         optional :username, type: String, desc: 'Username for deploy token. Default is `gitlab+deploy-token-{n}`'
diff --git a/lib/api/deployments.rb b/lib/api/deployments.rb
index 87144fd31cca2..cb1dca11e8726 100644
--- a/lib/api/deployments.rb
+++ b/lib/api/deployments.rb
@@ -2,7 +2,7 @@
 
 module API
   # Deployments RESTful API endpoints
-  class Deployments < Grape::API::Instance
+  class Deployments < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/lib/api/discussions.rb b/lib/api/discussions.rb
index 4e71e4c50de22..0dd1850e526b7 100644
--- a/lib/api/discussions.rb
+++ b/lib/api/discussions.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Discussions < Grape::API::Instance
+  class Discussions < Grape::API
     include PaginationParams
     helpers ::API::Helpers::NotesHelpers
     helpers ::RendersNotes
diff --git a/lib/api/environments.rb b/lib/api/environments.rb
index b825904e2c5f1..28019ce77961d 100644
--- a/lib/api/environments.rb
+++ b/lib/api/environments.rb
@@ -2,7 +2,7 @@
 
 module API
   # Environments RESTfull API endpoints
-  class Environments < Grape::API::Instance
+  class Environments < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/lib/api/error_tracking.rb b/lib/api/error_tracking.rb
index 64ec6f0a57a6f..14888037f5397 100644
--- a/lib/api/error_tracking.rb
+++ b/lib/api/error_tracking.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ErrorTracking < Grape::API::Instance
+  class ErrorTracking < Grape::API
     before { authenticate! }
 
     params do
diff --git a/lib/api/events.rb b/lib/api/events.rb
index 0b79431a76dd7..e4c017fab42b9 100644
--- a/lib/api/events.rb
+++ b/lib/api/events.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Events < Grape::API::Instance
+  class Events < Grape::API
     include PaginationParams
     include APIGuard
     helpers ::API::Helpers::EventsHelpers
diff --git a/lib/api/features.rb b/lib/api/features.rb
index 181c2fd4a6f7c..69b751e9bdbe1 100644
--- a/lib/api/features.rb
+++ b/lib/api/features.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Features < Grape::API::Instance
+  class Features < Grape::API
     before { authenticated_as_admin! }
 
     helpers do
diff --git a/lib/api/files.rb b/lib/api/files.rb
index 1e2f0e011eda4..76ab9a2190bda 100644
--- a/lib/api/files.rb
+++ b/lib/api/files.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Files < Grape::API::Instance
+  class Files < Grape::API
     include APIGuard
 
     FILE_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(file_path: API::NO_SLASH_URL_PART_REGEX)
diff --git a/lib/api/group_boards.rb b/lib/api/group_boards.rb
index 7efc12121d24c..88d04e70e1191 100644
--- a/lib/api/group_boards.rb
+++ b/lib/api/group_boards.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class GroupBoards < Grape::API::Instance
+  class GroupBoards < Grape::API
     include BoardsResponses
     include PaginationParams
 
diff --git a/lib/api/group_clusters.rb b/lib/api/group_clusters.rb
index c6d10f22bb450..2c12c6387fb60 100644
--- a/lib/api/group_clusters.rb
+++ b/lib/api/group_clusters.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class GroupClusters < Grape::API::Instance
+  class GroupClusters < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/lib/api/group_container_repositories.rb b/lib/api/group_container_repositories.rb
index d924d717c8552..7f95b411b3673 100644
--- a/lib/api/group_container_repositories.rb
+++ b/lib/api/group_container_repositories.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class GroupContainerRepositories < Grape::API::Instance
+  class GroupContainerRepositories < Grape::API
     include PaginationParams
 
     before { authorize_read_group_container_images! }
diff --git a/lib/api/group_export.rb b/lib/api/group_export.rb
index b5933ca4b940f..8ca5dfa082ece 100644
--- a/lib/api/group_export.rb
+++ b/lib/api/group_export.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class GroupExport < Grape::API::Instance
+  class GroupExport < Grape::API
     before do
       not_found! unless Feature.enabled?(:group_import_export, user_group, default_enabled: true)
 
diff --git a/lib/api/group_import.rb b/lib/api/group_import.rb
index a20523fd55f26..ed52506de147c 100644
--- a/lib/api/group_import.rb
+++ b/lib/api/group_import.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class GroupImport < Grape::API::Instance
+  class GroupImport < Grape::API
     MAXIMUM_FILE_SIZE = 50.megabytes.freeze
 
     helpers do
diff --git a/lib/api/group_labels.rb b/lib/api/group_labels.rb
index 56f2b769464f4..7585293031f0f 100644
--- a/lib/api/group_labels.rb
+++ b/lib/api/group_labels.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class GroupLabels < Grape::API::Instance
+  class GroupLabels < Grape::API
     include PaginationParams
     helpers ::API::Helpers::LabelHelpers
 
diff --git a/lib/api/group_milestones.rb b/lib/api/group_milestones.rb
index 05dc417e3b173..9e9f510128558 100644
--- a/lib/api/group_milestones.rb
+++ b/lib/api/group_milestones.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class GroupMilestones < Grape::API::Instance
+  class GroupMilestones < Grape::API
     include MilestoneResponses
     include PaginationParams
 
diff --git a/lib/api/group_variables.rb b/lib/api/group_variables.rb
index 7cf7584bf4c4d..916f89649a5ff 100644
--- a/lib/api/group_variables.rb
+++ b/lib/api/group_variables.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class GroupVariables < Grape::API::Instance
+  class GroupVariables < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/lib/api/groups.rb b/lib/api/groups.rb
index 7f42d8ed0d918..d375c35e8c0c4 100644
--- a/lib/api/groups.rb
+++ b/lib/api/groups.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Groups < Grape::API::Instance
+  class Groups < Grape::API
     include PaginationParams
     include Helpers::CustomAttributes
 
@@ -16,7 +16,7 @@ class Groups < Grape::API::Instance
 
       params :group_list_params do
         use :statistics_params
-        optional :skip_groups, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'Array of group ids to exclude from list'
+        optional :skip_groups, type: Array[Integer], desc: 'Array of group ids to exclude from list'
         optional :all_available, type: Boolean, desc: 'Show all group that you have access to'
         optional :search, type: String, desc: 'Search for a specific group'
         optional :owned, type: Boolean, default: false, desc: 'Limit by owned by authenticated user'
diff --git a/lib/api/helpers/merge_requests_helpers.rb b/lib/api/helpers/merge_requests_helpers.rb
index 00430fa08c655..73711a7e0ba15 100644
--- a/lib/api/helpers/merge_requests_helpers.rb
+++ b/lib/api/helpers/merge_requests_helpers.rb
@@ -24,7 +24,7 @@ module MergeRequestsHelpers
         optional :milestone, type: String, desc: 'Return merge requests for a specific milestone'
         optional :labels,
                  type: Array[String],
-                 coerce_with: Validations::Types::CommaSeparatedToArray.coerce,
+                 coerce_with: Validations::Types::LabelsList.coerce,
                  desc: 'Comma-separated list of label names'
         optional :with_labels_details, type: Boolean, desc: 'Return titles of labels and other details', default: false
         optional :created_after, type: DateTime, desc: 'Return merge requests created after the specified time'
diff --git a/lib/api/helpers/projects_helpers.rb b/lib/api/helpers/projects_helpers.rb
index b80d662f117ce..14c83114f3273 100644
--- a/lib/api/helpers/projects_helpers.rb
+++ b/lib/api/helpers/projects_helpers.rb
@@ -44,7 +44,7 @@ module ProjectsHelpers
         optional :request_access_enabled, type: Boolean, desc: 'Allow users to request member access'
         optional :only_allow_merge_if_pipeline_succeeds, type: Boolean, desc: 'Only allow to merge if builds succeed'
         optional :only_allow_merge_if_all_discussions_are_resolved, type: Boolean, desc: 'Only allow to merge if all discussions are resolved'
-        optional :tag_list, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'The list of tags for a project'
+        optional :tag_list, type: Array[String], desc: 'The list of tags for a project'
         # TODO: remove rubocop disable - https://gitlab.com/gitlab-org/gitlab/issues/14960
         optional :avatar, type: File, desc: 'Avatar image for project' # rubocop:disable Scalability/FileUploads
         optional :printing_merge_request_link_enabled, type: Boolean, desc: 'Show link to create/view merge request when pushing from the command line'
diff --git a/lib/api/import_github.rb b/lib/api/import_github.rb
index 986827e80be25..21d4928193eec 100644
--- a/lib/api/import_github.rb
+++ b/lib/api/import_github.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ImportGithub < Grape::API::Instance
+  class ImportGithub < Grape::API
     rescue_from Octokit::Unauthorized, with: :provider_unauthorized
 
     helpers do
diff --git a/lib/api/internal/base.rb b/lib/api/internal/base.rb
index eab8ba25410ca..564a00701c473 100644
--- a/lib/api/internal/base.rb
+++ b/lib/api/internal/base.rb
@@ -3,7 +3,7 @@
 module API
   # Internal access API
   module Internal
-    class Base < Grape::API::Instance
+    class Base < Grape::API
       before { authenticate_by_gitlab_shell_token! }
 
       before do
diff --git a/lib/api/internal/pages.rb b/lib/api/internal/pages.rb
index 5f8d23f15fa4d..6c8da414e4db7 100644
--- a/lib/api/internal/pages.rb
+++ b/lib/api/internal/pages.rb
@@ -3,7 +3,7 @@
 module API
   # Pages Internal API
   module Internal
-    class Pages < Grape::API::Instance
+    class Pages < Grape::API
       before do
         authenticate_gitlab_pages_request!
       end
diff --git a/lib/api/issues.rb b/lib/api/issues.rb
index 9ef1561f4237e..f27afd0055f50 100644
--- a/lib/api/issues.rb
+++ b/lib/api/issues.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Issues < Grape::API::Instance
+  class Issues < Grape::API
     include PaginationParams
     helpers Helpers::IssuesHelpers
     helpers Helpers::RateLimiter
@@ -11,9 +11,9 @@ class Issues < Grape::API::Instance
 
     helpers do
       params :negatable_issue_filter_params do
-        optional :labels, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'Comma-separated list of label names'
+        optional :labels, type: Array[String], coerce_with: Validations::Types::LabelsList.coerce, desc: 'Comma-separated list of label names'
         optional :milestone, type: String, desc: 'Milestone title'
-        optional :iids, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The IID array of issues'
+        optional :iids, type: Array[Integer], desc: 'The IID array of issues'
         optional :search, type: String, desc: 'Search issues for text present in the title, description, or any combination of these'
         optional :in, type: String, desc: '`title`, `description`, or a string joining them with comma'
 
@@ -63,10 +63,10 @@ class Issues < Grape::API::Instance
 
       params :issue_params do
         optional :description, type: String, desc: 'The description of an issue'
-        optional :assignee_ids, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The array of user IDs to assign issue'
+        optional :assignee_ids, type: Array[Integer], desc: 'The array of user IDs to assign issue'
         optional :assignee_id,  type: Integer, desc: '[Deprecated] The ID of a user to assign issue'
         optional :milestone_id, type: Integer, desc: 'The ID of a milestone to assign issue'
-        optional :labels, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'Comma-separated list of label names'
+        optional :labels, type: Array[String], coerce_with: Validations::Types::LabelsList.coerce, desc: 'Comma-separated list of label names'
         optional :due_date, type: String, desc: 'Date string in the format YEAR-MONTH-DAY'
         optional :confidential, type: Boolean, desc: 'Boolean parameter if the issue should be confidential'
         optional :discussion_locked, type: Boolean, desc: " Boolean parameter indicating if the issue's discussion is locked"
diff --git a/lib/api/job_artifacts.rb b/lib/api/job_artifacts.rb
index 321c14de1b932..920938ad453b7 100644
--- a/lib/api/job_artifacts.rb
+++ b/lib/api/job_artifacts.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class JobArtifacts < Grape::API::Instance
+  class JobArtifacts < Grape::API
     before { authenticate_non_get! }
 
     # EE::API::JobArtifacts would override the following helpers
diff --git a/lib/api/jobs.rb b/lib/api/jobs.rb
index 7a7dfcedecb4b..59f0dbe8a9b73 100644
--- a/lib/api/jobs.rb
+++ b/lib/api/jobs.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Jobs < Grape::API::Instance
+  class Jobs < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/lib/api/keys.rb b/lib/api/keys.rb
index c014641ca043e..b730e02706387 100644
--- a/lib/api/keys.rb
+++ b/lib/api/keys.rb
@@ -2,7 +2,7 @@
 
 module API
   # Keys API
-  class Keys < Grape::API::Instance
+  class Keys < Grape::API
     before { authenticate! }
 
     resource :keys do
diff --git a/lib/api/labels.rb b/lib/api/labels.rb
index edf4a8ca14eac..2b283d82e4aec 100644
--- a/lib/api/labels.rb
+++ b/lib/api/labels.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Labels < Grape::API::Instance
+  class Labels < Grape::API
     include PaginationParams
     helpers ::API::Helpers::LabelHelpers
 
diff --git a/lib/api/lint.rb b/lib/api/lint.rb
index f7796b1e9694d..a7672021db01b 100644
--- a/lib/api/lint.rb
+++ b/lib/api/lint.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Lint < Grape::API::Instance
+  class Lint < Grape::API
     namespace :ci do
       desc 'Validation of .gitlab-ci.yml content'
       params do
diff --git a/lib/api/lsif_data.rb b/lib/api/lsif_data.rb
index 338d6c533a4b1..a673ccb4af040 100644
--- a/lib/api/lsif_data.rb
+++ b/lib/api/lsif_data.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class LsifData < Grape::API::Instance
+  class LsifData < Grape::API
     MAX_FILE_SIZE = 10.megabytes
 
     before do
diff --git a/lib/api/markdown.rb b/lib/api/markdown.rb
index a0822271cca51..de77bef43ce90 100644
--- a/lib/api/markdown.rb
+++ b/lib/api/markdown.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Markdown < Grape::API::Instance
+  class Markdown < Grape::API
     params do
       requires :text, type: String, desc: "The markdown text to render"
       optional :gfm, type: Boolean, desc: "Render text using GitLab Flavored Markdown"
diff --git a/lib/api/members.rb b/lib/api/members.rb
index 2254a0b78988c..37d4ca29b684e 100644
--- a/lib/api/members.rb
+++ b/lib/api/members.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Members < Grape::API::Instance
+  class Members < Grape::API
     include PaginationParams
 
     before { authenticate! }
@@ -18,7 +18,7 @@ class Members < Grape::API::Instance
         end
         params do
           optional :query, type: String, desc: 'A query string to search for members'
-          optional :user_ids, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'Array of user ids to look up for membership'
+          optional :user_ids, type: Array[Integer], desc: 'Array of user ids to look up for membership'
           optional :show_seat_info, type: Boolean, desc: 'Show seat information for members'
           use :optional_filter_params_ee
           use :pagination
@@ -37,7 +37,7 @@ class Members < Grape::API::Instance
         end
         params do
           optional :query, type: String, desc: 'A query string to search for members'
-          optional :user_ids, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'Array of user ids to look up for membership'
+          optional :user_ids, type: Array[Integer], desc: 'Array of user ids to look up for membership'
           optional :show_seat_info, type: Boolean, desc: 'Show seat information for members'
           use :pagination
         end
diff --git a/lib/api/merge_request_diffs.rb b/lib/api/merge_request_diffs.rb
index 3e43fe8b257c1..6ad30aa56e0f5 100644
--- a/lib/api/merge_request_diffs.rb
+++ b/lib/api/merge_request_diffs.rb
@@ -2,7 +2,7 @@
 
 module API
   # MergeRequestDiff API
-  class MergeRequestDiffs < Grape::API::Instance
+  class MergeRequestDiffs < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index b7bc936fe2fff..d45786cdd3d78 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class MergeRequests < Grape::API::Instance
+  class MergeRequests < Grape::API
     include PaginationParams
 
     CONTEXT_COMMITS_POST_LIMIT = 20
@@ -177,9 +177,9 @@ def handle_merge_request_errors!(errors)
         params :optional_params do
           optional :description, type: String, desc: 'The description of the merge request'
           optional :assignee_id, type: Integer, desc: 'The ID of a user to assign the merge request'
-          optional :assignee_ids, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The array of user IDs to assign issue'
+          optional :assignee_ids, type: Array[Integer], desc: 'The array of user IDs to assign issue'
           optional :milestone_id, type: Integer, desc: 'The ID of a milestone to assign the merge request'
-          optional :labels, type: Array[String], coerce_with: Validations::Types::CommaSeparatedToArray.coerce, desc: 'Comma-separated list of label names'
+          optional :labels, type: Array[String], coerce_with: Validations::Types::LabelsList.coerce, desc: 'Comma-separated list of label names'
           optional :remove_source_branch, type: Boolean, desc: 'Remove source branch when merging'
           optional :allow_collaboration, type: Boolean, desc: 'Allow commits from members who can merge to the target branch'
           optional :allow_maintainer_to_push, type: Boolean, as: :allow_collaboration, desc: '[deprecated] See allow_collaboration'
@@ -194,7 +194,7 @@ def handle_merge_request_errors!(errors)
       end
       params do
         use :merge_requests_params
-        optional :iids, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The IID array of merge requests'
+        optional :iids, type: Array[Integer], desc: 'The IID array of merge requests'
       end
       get ":id/merge_requests" do
         authorize! :read_merge_request, user_project
diff --git a/lib/api/metrics/dashboard/annotations.rb b/lib/api/metrics/dashboard/annotations.rb
index d71a4e9d736a2..432fa3ac0c92c 100644
--- a/lib/api/metrics/dashboard/annotations.rb
+++ b/lib/api/metrics/dashboard/annotations.rb
@@ -3,7 +3,7 @@
 module API
   module Metrics
     module Dashboard
-      class Annotations < Grape::API::Instance
+      class Annotations < Grape::API
         desc 'Create a new monitoring dashboard annotation' do
           success Entities::Metrics::Dashboard::Annotation
         end
diff --git a/lib/api/milestone_responses.rb b/lib/api/milestone_responses.rb
index 8ff885983bccd..62e159ab0034a 100644
--- a/lib/api/milestone_responses.rb
+++ b/lib/api/milestone_responses.rb
@@ -15,7 +15,7 @@ module MilestoneResponses
         params :list_params do
           optional :state, type: String, values: %w[active closed all], default: 'all',
                            desc: 'Return "active", "closed", or "all" milestones'
-          optional :iids, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'The IIDs of the milestones'
+          optional :iids, type: Array[Integer], desc: 'The IIDs of the milestones'
           optional :title, type: String, desc: 'The title of the milestones'
           optional :search, type: String, desc: 'The search criteria for the title or description of the milestone'
           use :pagination
diff --git a/lib/api/namespaces.rb b/lib/api/namespaces.rb
index e1f279df045a7..e40a5dde7ce7d 100644
--- a/lib/api/namespaces.rb
+++ b/lib/api/namespaces.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Namespaces < Grape::API::Instance
+  class Namespaces < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/lib/api/notes.rb b/lib/api/notes.rb
index 4fb7bffb3d55c..3eafc1ead77bd 100644
--- a/lib/api/notes.rb
+++ b/lib/api/notes.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Notes < Grape::API::Instance
+  class Notes < Grape::API
     include PaginationParams
     helpers ::API::Helpers::NotesHelpers
 
diff --git a/lib/api/notification_settings.rb b/lib/api/notification_settings.rb
index f8b621c1c3845..8cb46bd3ad6a1 100644
--- a/lib/api/notification_settings.rb
+++ b/lib/api/notification_settings.rb
@@ -2,7 +2,7 @@
 
 module API
   # notification_settings API
-  class NotificationSettings < Grape::API::Instance
+  class NotificationSettings < Grape::API
     before { authenticate! }
 
     helpers ::API::Helpers::MembersHelpers
diff --git a/lib/api/pages.rb b/lib/api/pages.rb
index 79a6b527581ea..ee7fe669519aa 100644
--- a/lib/api/pages.rb
+++ b/lib/api/pages.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Pages < Grape::API::Instance
+  class Pages < Grape::API
     before do
       require_pages_config_enabled!
       authenticated_with_can_read_all_resources!
diff --git a/lib/api/pages_domains.rb b/lib/api/pages_domains.rb
index 7d27b575efa20..4c3d2d131acf3 100644
--- a/lib/api/pages_domains.rb
+++ b/lib/api/pages_domains.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class PagesDomains < Grape::API::Instance
+  class PagesDomains < Grape::API
     include PaginationParams
 
     PAGES_DOMAINS_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(domain: API::NO_SLASH_URL_PART_REGEX)
diff --git a/lib/api/pagination_params.rb b/lib/api/pagination_params.rb
index a232b58d3f7ef..ae03595eb25eb 100644
--- a/lib/api/pagination_params.rb
+++ b/lib/api/pagination_params.rb
@@ -4,7 +4,7 @@ module API
   # Concern for declare pagination params.
   #
   # @example
-  #   class CustomApiResource < Grape::API::Instance
+  #   class CustomApiResource < Grape::API
   #     include PaginationParams
   #
   #     params do
diff --git a/lib/api/pipeline_schedules.rb b/lib/api/pipeline_schedules.rb
index 46058f45bcba1..edc99590cdb27 100644
--- a/lib/api/pipeline_schedules.rb
+++ b/lib/api/pipeline_schedules.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class PipelineSchedules < Grape::API::Instance
+  class PipelineSchedules < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/lib/api/pipelines.rb b/lib/api/pipelines.rb
index f881d5b63e66f..06f8920b37cfa 100644
--- a/lib/api/pipelines.rb
+++ b/lib/api/pipelines.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Pipelines < Grape::API::Instance
+  class Pipelines < Grape::API
     include PaginationParams
 
     before { authenticate_non_get! }
diff --git a/lib/api/project_clusters.rb b/lib/api/project_clusters.rb
index e1dfb647fa08d..299301aabc46c 100644
--- a/lib/api/project_clusters.rb
+++ b/lib/api/project_clusters.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProjectClusters < Grape::API::Instance
+  class ProjectClusters < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/lib/api/project_container_repositories.rb b/lib/api/project_container_repositories.rb
index ed15bd92f1b93..555fd98b451f2 100644
--- a/lib/api/project_container_repositories.rb
+++ b/lib/api/project_container_repositories.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProjectContainerRepositories < Grape::API::Instance
+  class ProjectContainerRepositories < Grape::API
     include PaginationParams
 
     REPOSITORY_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(
diff --git a/lib/api/project_events.rb b/lib/api/project_events.rb
index 726e693826e3c..734311e1142dd 100644
--- a/lib/api/project_events.rb
+++ b/lib/api/project_events.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProjectEvents < Grape::API::Instance
+  class ProjectEvents < Grape::API
     include PaginationParams
     include APIGuard
     helpers ::API::Helpers::EventsHelpers
diff --git a/lib/api/project_export.rb b/lib/api/project_export.rb
index 797c6097b0422..9fd9d13a20c2a 100644
--- a/lib/api/project_export.rb
+++ b/lib/api/project_export.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProjectExport < Grape::API::Instance
+  class ProjectExport < Grape::API
     helpers Helpers::RateLimiter
 
     before do
diff --git a/lib/api/project_hooks.rb b/lib/api/project_hooks.rb
index 7cea44e63049c..0e7576c9243c7 100644
--- a/lib/api/project_hooks.rb
+++ b/lib/api/project_hooks.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProjectHooks < Grape::API::Instance
+  class ProjectHooks < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/lib/api/project_import.rb b/lib/api/project_import.rb
index 9be192a80e01a..0e83686cab2d4 100644
--- a/lib/api/project_import.rb
+++ b/lib/api/project_import.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProjectImport < Grape::API::Instance
+  class ProjectImport < Grape::API
     include PaginationParams
 
     MAXIMUM_FILE_SIZE = 50.megabytes
diff --git a/lib/api/project_milestones.rb b/lib/api/project_milestones.rb
index 71388fd500a40..8643854a655b1 100644
--- a/lib/api/project_milestones.rb
+++ b/lib/api/project_milestones.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProjectMilestones < Grape::API::Instance
+  class ProjectMilestones < Grape::API
     include PaginationParams
     include MilestoneResponses
 
diff --git a/lib/api/project_snapshots.rb b/lib/api/project_snapshots.rb
index 360000861fcc4..175fbb2ce928b 100644
--- a/lib/api/project_snapshots.rb
+++ b/lib/api/project_snapshots.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProjectSnapshots < Grape::API::Instance
+  class ProjectSnapshots < Grape::API
     helpers ::API::Helpers::ProjectSnapshotsHelpers
 
     before { authorize_read_git_snapshot! }
diff --git a/lib/api/project_snippets.rb b/lib/api/project_snippets.rb
index c3e4c806a597a..f5ca2f4d5a1a3 100644
--- a/lib/api/project_snippets.rb
+++ b/lib/api/project_snippets.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProjectSnippets < Grape::API::Instance
+  class ProjectSnippets < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/lib/api/project_statistics.rb b/lib/api/project_statistics.rb
index 2196801096fcd..14ee0f75513cd 100644
--- a/lib/api/project_statistics.rb
+++ b/lib/api/project_statistics.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProjectStatistics < Grape::API::Instance
+  class ProjectStatistics < Grape::API
     before do
       authenticate!
       authorize! :daily_statistics, user_project
diff --git a/lib/api/project_templates.rb b/lib/api/project_templates.rb
index 3eded5606c199..119902a189c77 100644
--- a/lib/api/project_templates.rb
+++ b/lib/api/project_templates.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProjectTemplates < Grape::API::Instance
+  class ProjectTemplates < Grape::API
     include PaginationParams
 
     TEMPLATE_TYPES = %w[dockerfiles gitignores gitlab_ci_ymls licenses].freeze
diff --git a/lib/api/projects.rb b/lib/api/projects.rb
index 7c98a749bf7e8..ee0731a331f96 100644
--- a/lib/api/projects.rb
+++ b/lib/api/projects.rb
@@ -3,7 +3,7 @@
 require_dependency 'declarative_policy'
 
 module API
-  class Projects < Grape::API::Instance
+  class Projects < Grape::API
     include PaginationParams
     include Helpers::CustomAttributes
 
@@ -520,7 +520,7 @@ def translate_params_for_compatibility(params)
       end
       params do
         optional :search, type: String, desc: 'Return list of users matching the search criteria'
-        optional :skip_users, type: Array[Integer], coerce_with: ::API::Validations::Types::CommaSeparatedToIntegerArray.coerce, desc: 'Filter out users with the specified IDs'
+        optional :skip_users, type: Array[Integer], desc: 'Filter out users with the specified IDs'
         use :pagination
       end
       get ':id/users' do
diff --git a/lib/api/protected_branches.rb b/lib/api/protected_branches.rb
index b0a7f898eeca1..1fd86d1e72075 100644
--- a/lib/api/protected_branches.rb
+++ b/lib/api/protected_branches.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProtectedBranches < Grape::API::Instance
+  class ProtectedBranches < Grape::API
     include PaginationParams
 
     BRANCH_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(name: API::NO_SLASH_URL_PART_REGEX)
diff --git a/lib/api/protected_tags.rb b/lib/api/protected_tags.rb
index aaa31cb7cc6c7..ee13473c8485e 100644
--- a/lib/api/protected_tags.rb
+++ b/lib/api/protected_tags.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ProtectedTags < Grape::API::Instance
+  class ProtectedTags < Grape::API
     include PaginationParams
 
     TAG_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(name: API::NO_SLASH_URL_PART_REGEX)
diff --git a/lib/api/release/links.rb b/lib/api/release/links.rb
index 16154aac7b5e1..f72230c084c5b 100644
--- a/lib/api/release/links.rb
+++ b/lib/api/release/links.rb
@@ -2,7 +2,7 @@
 
 module API
   module Release
-    class Links < Grape::API::Instance
+    class Links < Grape::API
       include PaginationParams
 
       RELEASE_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS
diff --git a/lib/api/releases.rb b/lib/api/releases.rb
index ae11561205e77..95b3e90323c65 100644
--- a/lib/api/releases.rb
+++ b/lib/api/releases.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Releases < Grape::API::Instance
+  class Releases < Grape::API
     include PaginationParams
 
     RELEASE_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS
diff --git a/lib/api/remote_mirrors.rb b/lib/api/remote_mirrors.rb
index ef83d8de151d6..7e484eb888516 100644
--- a/lib/api/remote_mirrors.rb
+++ b/lib/api/remote_mirrors.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class RemoteMirrors < Grape::API::Instance
+  class RemoteMirrors < Grape::API
     include PaginationParams
 
     before do
diff --git a/lib/api/repositories.rb b/lib/api/repositories.rb
index 37f134dcffa01..0b2df85f61fc2 100644
--- a/lib/api/repositories.rb
+++ b/lib/api/repositories.rb
@@ -3,7 +3,7 @@
 require 'mime/types'
 
 module API
-  class Repositories < Grape::API::Instance
+  class Repositories < Grape::API
     include PaginationParams
 
     before { authorize! :download_code, user_project }
@@ -139,7 +139,7 @@ def assign_blob_vars!
         success Entities::Commit
       end
       params do
-        requires :refs, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce
+        requires :refs, type: Array[String]
       end
       get ':id/repository/merge_base' do
         refs = params[:refs]
diff --git a/lib/api/resource_label_events.rb b/lib/api/resource_label_events.rb
index 60bcee094ad78..f7f7c881f4aa8 100644
--- a/lib/api/resource_label_events.rb
+++ b/lib/api/resource_label_events.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class ResourceLabelEvents < Grape::API::Instance
+  class ResourceLabelEvents < Grape::API
     include PaginationParams
     helpers ::API::Helpers::NotesHelpers
 
diff --git a/lib/api/runner.rb b/lib/api/runner.rb
index aac261757157d..9095aba7340f2 100644
--- a/lib/api/runner.rb
+++ b/lib/api/runner.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Runner < Grape::API::Instance
+  class Runner < Grape::API
     helpers ::API::Helpers::Runner
 
     resource :runners do
@@ -18,7 +18,7 @@ class Runner < Grape::API::Instance
         optional :access_level, type: String, values: Ci::Runner.access_levels.keys,
                                 desc: 'The access_level of the runner'
         optional :run_untagged, type: Boolean, desc: 'Should Runner handle untagged jobs'
-        optional :tag_list, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: %q(List of Runner's tags)
+        optional :tag_list, type: Array[String], desc: %q(List of Runner's tags)
         optional :maximum_timeout, type: Integer, desc: 'Maximum timeout set when this Runner will handle the job'
       end
       post '/' do
diff --git a/lib/api/runners.rb b/lib/api/runners.rb
index f1adc9e5aff4e..43ee1dd1f71e2 100644
--- a/lib/api/runners.rb
+++ b/lib/api/runners.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Runners < Grape::API::Instance
+  class Runners < Grape::API
     include PaginationParams
 
     before { authenticate! }
@@ -17,7 +17,7 @@ class Runners < Grape::API::Instance
                         desc: 'The type of the runners to show'
         optional :status, type: String, values: Ci::Runner::AVAILABLE_STATUSES,
                           desc: 'The status of the runners to show'
-        optional :tag_list, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'The tags of the runners to show'
+        optional :tag_list, type: Array[String], desc: 'The tags of the runners to show'
         use :pagination
       end
       get do
@@ -40,7 +40,7 @@ class Runners < Grape::API::Instance
                         desc: 'The type of the runners to show'
         optional :status, type: String, values: Ci::Runner::AVAILABLE_STATUSES,
                           desc: 'The status of the runners to show'
-        optional :tag_list, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'The tags of the runners to show'
+        optional :tag_list, type: Array[String], desc: 'The tags of the runners to show'
         use :pagination
       end
       get 'all' do
@@ -75,7 +75,7 @@ class Runners < Grape::API::Instance
         requires :id, type: Integer, desc: 'The ID of the runner'
         optional :description, type: String, desc: 'The description of the runner'
         optional :active, type: Boolean, desc: 'The state of a runner'
-        optional :tag_list, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'The list of tags for a runner'
+        optional :tag_list, type: Array[String], desc: 'The list of tags for a runner'
         optional :run_untagged, type: Boolean, desc: 'Flag indicating the runner can execute untagged jobs'
         optional :locked, type: Boolean, desc: 'Flag indicating the runner is locked'
         optional :access_level, type: String, values: Ci::Runner.access_levels.keys,
@@ -145,7 +145,7 @@ class Runners < Grape::API::Instance
                         desc: 'The type of the runners to show'
         optional :status, type: String, values: Ci::Runner::AVAILABLE_STATUSES,
                           desc: 'The status of the runners to show'
-        optional :tag_list, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'The tags of the runners to show'
+        optional :tag_list, type: Array[String], desc: 'The tags of the runners to show'
         use :pagination
       end
       get ':id/runners' do
@@ -208,7 +208,7 @@ class Runners < Grape::API::Instance
                  desc: 'The type of the runners to show'
         optional :status, type: String, values: Ci::Runner::AVAILABLE_STATUSES,
                  desc: 'The status of the runners to show'
-        optional :tag_list, type: Array[String], coerce_with: ::API::Validations::Types::CommaSeparatedToArray.coerce, desc: 'The tags of the runners to show'
+        optional :tag_list, type: Array[String], desc: 'The tags of the runners to show'
         use :pagination
       end
       get ':id/runners' do
diff --git a/lib/api/search.rb b/lib/api/search.rb
index e685f2c4afea2..ed52a4fc8f247 100644
--- a/lib/api/search.rb
+++ b/lib/api/search.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Search < Grape::API::Instance
+  class Search < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/lib/api/services.rb b/lib/api/services.rb
index 9ee1822339c8c..5fd5c6bd9b094 100644
--- a/lib/api/services.rb
+++ b/lib/api/services.rb
@@ -1,6 +1,6 @@
 # frozen_string_literal: true
 module API
-  class Services < Grape::API::Instance
+  class Services < Grape::API
     services = Helpers::ServicesHelpers.services
     service_classes = Helpers::ServicesHelpers.service_classes
 
diff --git a/lib/api/settings.rb b/lib/api/settings.rb
index 0849a0ff9452c..09644d42e8f48 100644
--- a/lib/api/settings.rb
+++ b/lib/api/settings.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Settings < Grape::API::Instance
+  class Settings < Grape::API
     before { authenticated_as_admin! }
 
     helpers Helpers::SettingsHelpers
@@ -49,7 +49,7 @@ def filter_attributes_using_license(attrs)
       optional :default_project_visibility, type: String, values: Gitlab::VisibilityLevel.string_values, desc: 'The default project visibility'
       optional :default_projects_limit, type: Integer, desc: 'The maximum number of personal projects'
       optional :default_snippet_visibility, type: String, values: Gitlab::VisibilityLevel.string_values, desc: 'The default snippet visibility'
-      optional :disabled_oauth_sign_in_sources, type: Array[String], coerce_with: Validations::Types::CommaSeparatedToArray.coerce, desc: 'Disable certain OAuth sign-in sources'
+      optional :disabled_oauth_sign_in_sources, type: Array[String], desc: 'Disable certain OAuth sign-in sources'
       optional :domain_blacklist_enabled, type: Boolean, desc: 'Enable domain blacklist for sign ups'
       optional :domain_blacklist, type: Array[String], coerce_with: Validations::Types::CommaSeparatedToArray.coerce, desc: 'Users with e-mail addresses that match these domain(s) will NOT be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com'
       optional :domain_whitelist, type: Array[String], coerce_with: Validations::Types::CommaSeparatedToArray.coerce, desc: 'ONLY users with e-mail addresses that match these domain(s) will be able to sign-up. Wildcards allowed. Use separate lines for multiple entries. Ex: domain.com, *.domain.com'
@@ -79,8 +79,7 @@ def filter_attributes_using_license(attrs)
         requires :housekeeping_incremental_repack_period, type: Integer, desc: "Number of Git pushes after which an incremental 'git repack' is run."
       end
       optional :html_emails_enabled, type: Boolean, desc: 'By default GitLab sends emails in HTML and plain text formats so mail clients can choose what format to use. Disable this option if you only want to send emails in plain text format.'
-      optional :import_sources, type: Array[String], coerce_with: Validations::Types::CommaSeparatedToArray.coerce,
-                                values: %w[github bitbucket bitbucket_server gitlab google_code fogbugz git gitlab_project gitea manifest phabricator],
+      optional :import_sources, type: Array[String], values: %w[github bitbucket bitbucket_server gitlab google_code fogbugz git gitlab_project gitea manifest phabricator],
                                 desc: 'Enabled sources for code import during project creation. OmniAuth must be configured for GitHub, Bitbucket, and GitLab.com'
       optional :max_artifacts_size, type: Integer, desc: "Set the maximum file size for each job's artifacts"
       optional :max_attachment_size, type: Integer, desc: 'Maximum attachment size in MB'
@@ -122,12 +121,12 @@ def filter_attributes_using_license(attrs)
         requires :recaptcha_private_key, type: String, desc: 'Generate private key at http://www.google.com/recaptcha'
       end
       optional :repository_checks_enabled, type: Boolean, desc: "GitLab will periodically run 'git fsck' in all project and wiki repositories to look for silent disk corruption issues."
-      optional :repository_storages, type: Array[String], coerce_with: Validations::Types::CommaSeparatedToArray.coerce, desc: 'Storage paths for new projects'
+      optional :repository_storages, type: Array[String], desc: 'Storage paths for new projects'
       optional :require_two_factor_authentication, type: Boolean, desc: 'Require all users to set up Two-factor authentication'
       given require_two_factor_authentication: ->(val) { val } do
         requires :two_factor_grace_period, type: Integer, desc: 'Amount of time (in hours) that users are allowed to skip forced configuration of two-factor authentication'
       end
-      optional :restricted_visibility_levels, type: Array[String], coerce_with: Validations::Types::CommaSeparatedToArray.coerce, desc: 'Selected levels cannot be used by non-admin users for groups, projects or snippets. If the public level is restricted, user profiles are only visible to logged in users.'
+      optional :restricted_visibility_levels, type: Array[String], desc: 'Selected levels cannot be used by non-admin users for groups, projects or snippets. If the public level is restricted, user profiles are only visible to logged in users.'
       optional :send_user_confirmation_email, type: Boolean, desc: 'Send confirmation email on sign-up'
       optional :session_expire_delay, type: Integer, desc: 'Session duration in minutes. GitLab restart is required to apply changes.'
       optional :shared_runners_enabled, type: Boolean, desc: 'Enable shared runners for new projects'
diff --git a/lib/api/sidekiq_metrics.rb b/lib/api/sidekiq_metrics.rb
index de1373144e373..693c20cb73aa3 100644
--- a/lib/api/sidekiq_metrics.rb
+++ b/lib/api/sidekiq_metrics.rb
@@ -3,7 +3,7 @@
 require 'sidekiq/api'
 
 module API
-  class SidekiqMetrics < Grape::API::Instance
+  class SidekiqMetrics < Grape::API
     before { authenticated_as_admin! }
 
     helpers do
diff --git a/lib/api/snippets.rb b/lib/api/snippets.rb
index 905b1c4d52b6a..b89de93af1bbe 100644
--- a/lib/api/snippets.rb
+++ b/lib/api/snippets.rb
@@ -2,7 +2,7 @@
 
 module API
   # Snippets API
-  class Snippets < Grape::API::Instance
+  class Snippets < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/lib/api/statistics.rb b/lib/api/statistics.rb
index 3869fd3ac7652..d2dce34dfa5b9 100644
--- a/lib/api/statistics.rb
+++ b/lib/api/statistics.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Statistics < Grape::API::Instance
+  class Statistics < Grape::API
     before { authenticated_as_admin! }
 
     COUNTED_ITEMS = [Project, User, Group, ForkNetworkMember, ForkNetwork, Issue,
diff --git a/lib/api/submodules.rb b/lib/api/submodules.rb
index 34d21d3d7d86e..72d7d9941020a 100644
--- a/lib/api/submodules.rb
+++ b/lib/api/submodules.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Submodules < Grape::API::Instance
+  class Submodules < Grape::API
     before { authenticate! }
 
     helpers do
diff --git a/lib/api/subscriptions.rb b/lib/api/subscriptions.rb
index 533663fb087ef..dfb54446ddf31 100644
--- a/lib/api/subscriptions.rb
+++ b/lib/api/subscriptions.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Subscriptions < Grape::API::Instance
+  class Subscriptions < Grape::API
     helpers ::API::Helpers::LabelHelpers
 
     before { authenticate! }
diff --git a/lib/api/suggestions.rb b/lib/api/suggestions.rb
index cf951ba497e5d..d008d1b9e97f0 100644
--- a/lib/api/suggestions.rb
+++ b/lib/api/suggestions.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Suggestions < Grape::API::Instance
+  class Suggestions < Grape::API
     before { authenticate! }
 
     resource :suggestions do
diff --git a/lib/api/system_hooks.rb b/lib/api/system_hooks.rb
index d8e0a425625d9..51fae0e54aaca 100644
--- a/lib/api/system_hooks.rb
+++ b/lib/api/system_hooks.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class SystemHooks < Grape::API::Instance
+  class SystemHooks < Grape::API
     include PaginationParams
 
     before do
diff --git a/lib/api/tags.rb b/lib/api/tags.rb
index c1fbd3ca7c6d2..796b14506022d 100644
--- a/lib/api/tags.rb
+++ b/lib/api/tags.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Tags < Grape::API::Instance
+  class Tags < Grape::API
     include PaginationParams
 
     TAG_ENDPOINT_REQUIREMENTS = API::NAMESPACE_OR_PROJECT_REQUIREMENTS.merge(tag_name: API::NO_SLASH_URL_PART_REGEX)
diff --git a/lib/api/templates.rb b/lib/api/templates.rb
index 80a97aae4296f..51f357d94770a 100644
--- a/lib/api/templates.rb
+++ b/lib/api/templates.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Templates < Grape::API::Instance
+  class Templates < Grape::API
     include PaginationParams
 
     GLOBAL_TEMPLATE_TYPES = {
diff --git a/lib/api/terraform/state.rb b/lib/api/terraform/state.rb
index 7192c33a41f3d..5141d1fd49939 100644
--- a/lib/api/terraform/state.rb
+++ b/lib/api/terraform/state.rb
@@ -4,7 +4,7 @@
 
 module API
   module Terraform
-    class State < Grape::API::Instance
+    class State < Grape::API
       include ::Gitlab::Utils::StrongMemoize
 
       default_format :json
diff --git a/lib/api/todos.rb b/lib/api/todos.rb
index 8a054adf3b828..02b8bb55274f1 100644
--- a/lib/api/todos.rb
+++ b/lib/api/todos.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Todos < Grape::API::Instance
+  class Todos < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/lib/api/triggers.rb b/lib/api/triggers.rb
index 8590487cf718c..e1829403941d5 100644
--- a/lib/api/triggers.rb
+++ b/lib/api/triggers.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Triggers < Grape::API::Instance
+  class Triggers < Grape::API
     include PaginationParams
 
     HTTP_GITLAB_EVENT_HEADER = "HTTP_#{WebHookService::GITLAB_EVENT_HEADER}".underscore.upcase
diff --git a/lib/api/user_counts.rb b/lib/api/user_counts.rb
index 90127ecbc7369..8df4b381bbfec 100644
--- a/lib/api/user_counts.rb
+++ b/lib/api/user_counts.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class UserCounts < Grape::API::Instance
+  class UserCounts < Grape::API
     resource :user_counts do
       desc 'Return the user specific counts' do
         detail 'Open MR Count'
diff --git a/lib/api/users.rb b/lib/api/users.rb
index c46c3a45514d8..c986414c223c8 100644
--- a/lib/api/users.rb
+++ b/lib/api/users.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Users < Grape::API::Instance
+  class Users < Grape::API
     include PaginationParams
     include APIGuard
     include Helpers::CustomAttributes
diff --git a/lib/api/validations/types/comma_separated_to_array.rb b/lib/api/validations/types/comma_separated_to_array.rb
index 409eb67a3d33e..b551878abd1a8 100644
--- a/lib/api/validations/types/comma_separated_to_array.rb
+++ b/lib/api/validations/types/comma_separated_to_array.rb
@@ -10,7 +10,7 @@ def self.coerce
             when String
               value.split(',').map(&:strip)
             when Array
-              value.flat_map { |v| v.to_s.split(',').map(&:strip) }
+              value.map { |v| v.to_s.split(',').map(&:strip) }.flatten
             else
               []
             end
diff --git a/lib/api/validations/types/comma_separated_to_integer_array.rb b/lib/api/validations/types/comma_separated_to_integer_array.rb
deleted file mode 100644
index b8ab08b3fd407..0000000000000
--- a/lib/api/validations/types/comma_separated_to_integer_array.rb
+++ /dev/null
@@ -1,15 +0,0 @@
-# frozen_string_literal: true
-
-module API
-  module Validations
-    module Types
-      class CommaSeparatedToIntegerArray < CommaSeparatedToArray
-        def self.coerce
-          lambda do |value|
-            super.call(value).map(&:to_i)
-          end
-        end
-      end
-    end
-  end
-end
diff --git a/lib/api/validations/types/labels_list.rb b/lib/api/validations/types/labels_list.rb
new file mode 100644
index 0000000000000..60277b99106ab
--- /dev/null
+++ b/lib/api/validations/types/labels_list.rb
@@ -0,0 +1,24 @@
+# frozen_string_literal: true
+
+module API
+  module Validations
+    module Types
+      class LabelsList
+        def self.coerce
+          lambda do |value|
+            case value
+            when String
+              value.split(',').map(&:strip)
+            when Array
+              value.flat_map { |v| v.to_s.split(',').map(&:strip) }
+            when LabelsList
+              value
+            else
+              []
+            end
+          end
+        end
+      end
+    end
+  end
+end
diff --git a/lib/api/validations/types/safe_file.rb b/lib/api/validations/types/safe_file.rb
new file mode 100644
index 0000000000000..53b5790bfa21d
--- /dev/null
+++ b/lib/api/validations/types/safe_file.rb
@@ -0,0 +1,15 @@
+# frozen_string_literal: true
+
+# This module overrides the Grape type validator defined in
+# https://github.com/ruby-grape/grape/blob/master/lib/grape/validations/types/file.rb
+module API
+  module Validations
+    module Types
+      class SafeFile < ::Grape::Validations::Types::File
+        def value_coerced?(value)
+          super && value[:tempfile].is_a?(Tempfile)
+        end
+      end
+    end
+  end
+end
diff --git a/lib/api/validations/types/workhorse_file.rb b/lib/api/validations/types/workhorse_file.rb
index e65e94fc8db70..18d111f655615 100644
--- a/lib/api/validations/types/workhorse_file.rb
+++ b/lib/api/validations/types/workhorse_file.rb
@@ -3,14 +3,15 @@
 module API
   module Validations
     module Types
-      class WorkhorseFile
-        def self.parse(value)
-          raise "#{value.class} is not an UploadedFile type" unless parsed?(value)
-
-          value
+      class WorkhorseFile < Virtus::Attribute
+        def coerce(input)
+          # Processing of multipart file objects
+          # is already taken care of by Gitlab::Middleware::Multipart.
+          # Nothing to do here.
+          input
         end
 
-        def self.parsed?(value)
+        def value_coerced?(value)
           value.is_a?(::UploadedFile)
         end
       end
diff --git a/lib/api/variables.rb b/lib/api/variables.rb
index 8740915caefe5..192b06b8a1b06 100644
--- a/lib/api/variables.rb
+++ b/lib/api/variables.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Variables < Grape::API::Instance
+  class Variables < Grape::API
     include PaginationParams
 
     before { authenticate! }
diff --git a/lib/api/version.rb b/lib/api/version.rb
index 6a480fc2bd901..2d8c90260fa30 100644
--- a/lib/api/version.rb
+++ b/lib/api/version.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Version < Grape::API::Instance
+  class Version < Grape::API
     helpers ::API::Helpers::GraphqlHelpers
     include APIGuard
 
diff --git a/lib/api/wikis.rb b/lib/api/wikis.rb
index e13b5d4f1c55b..a2146406690f3 100644
--- a/lib/api/wikis.rb
+++ b/lib/api/wikis.rb
@@ -1,7 +1,7 @@
 # frozen_string_literal: true
 
 module API
-  class Wikis < Grape::API::Instance
+  class Wikis < Grape::API
     helpers do
       def commit_params(attrs)
         # In order to avoid service disruption this can work with an old workhorse without the acceleration
@@ -117,7 +117,7 @@ def commit_params(attrs)
         success Entities::WikiAttachment
       end
       params do
-        requires :file, types: [Rack::Multipart::UploadedFile, ::API::Validations::Types::WorkhorseFile], desc: 'The attachment file to be uploaded'
+        requires :file, types: [::API::Validations::Types::SafeFile, ::API::Validations::Types::WorkhorseFile], desc: 'The attachment file to be uploaded'
         optional :branch, type: String, desc: 'The name of the branch'
       end
       post ":id/wikis/attachments" do
diff --git a/rubocop/cop/api/grape_api_instance.rb b/rubocop/cop/api/grape_api_instance.rb
deleted file mode 100644
index de11b9ef3f6e1..0000000000000
--- a/rubocop/cop/api/grape_api_instance.rb
+++ /dev/null
@@ -1,42 +0,0 @@
-# frozen_string_literal: true
-
-module RuboCop
-  module Cop
-    module API
-      class GrapeAPIInstance < RuboCop::Cop::Cop
-        # This cop checks that APIs subclass Grape::API::Instance with Grape v1.3+.
-        #
-        # @example
-        #
-        # # bad
-        # module API
-        #   class Projects < Grape::API
-        #   end
-        # end
-        #
-        # # good
-        # module API
-        #   class Projects < Grape::API::Instance
-        #   end
-        # end
-        MSG = 'Inherit from Grape::API::Instance instead of Grape::API. ' \
-              'For more details check the https://gitlab.com/gitlab-org/gitlab/-/issues/215230.'
-
-        def_node_matcher :grape_api_definition, <<~PATTERN
-          (class
-            (const _ _)
-            (const
-              (const nil? :Grape) :API)
-            ...
-          )
-        PATTERN
-
-        def on_class(node)
-          grape_api_definition(node) do
-            add_offense(node.children[1])
-          end
-        end
-      end
-    end
-  end
-end
diff --git a/rubocop/cop/api/grape_array_missing_coerce.rb b/rubocop/cop/api/grape_array_missing_coerce.rb
deleted file mode 100644
index 3d7a6a72d818b..0000000000000
--- a/rubocop/cop/api/grape_array_missing_coerce.rb
+++ /dev/null
@@ -1,83 +0,0 @@
-# frozen_string_literal: true
-
-module RuboCop
-  module Cop
-    module API
-      class GrapeArrayMissingCoerce < RuboCop::Cop::Cop
-        # This cop checks that Grape API parameters using an Array type
-        # implement a coerce_with method:
-        #
-        # https://github.com/ruby-grape/grape/blob/master/UPGRADING.md#ensure-that-array-types-have-explicit-coercions
-        #
-        # @example
-        #
-        # # bad
-        # requires :values, type: Array[String]
-        #
-        # # good
-        # requires :values, type: Array[String], coerce_with: Validations::Types::CommaSeparatedToArray.coerce
-        #
-        # end
-        MSG = 'This Grape parameter defines an Array but is missing a coerce_with definition. ' \
-          'For more details, see https://github.com/ruby-grape/grape/blob/master/UPGRADING.md#ensure-that-array-types-have-explicit-coercions'
-
-        def_node_matcher :grape_api_instance?, <<~PATTERN
-          (class
-            (const _ _)
-            (const
-              (const
-                (const nil? :Grape) :API) :Instance)
-            ...
-          )
-        PATTERN
-
-        def_node_matcher :grape_api_param_block?, <<~PATTERN
-          (send _ {:requires :optional}
-            (sym _)
-            $_)
-        PATTERN
-
-        def_node_matcher :grape_type_def?, <<~PATTERN
-           (sym :type)
-        PATTERN
-
-        def_node_matcher :grape_array_type?, <<~PATTERN
-           (send
-             (const nil? :Array) :[]
-             (const nil? _))
-        PATTERN
-
-        def_node_matcher :grape_coerce_with?, <<~PATTERN
-          (sym :coerce_with)
-        PATTERN
-
-        def on_class(node)
-          @grape_api ||= grape_api_instance?(node)
-        end
-
-        def on_send(node)
-          return unless @grape_api
-
-          match = grape_api_param_block?(node)
-
-          return unless match.is_a?(RuboCop::AST::HashNode)
-
-          is_array_type = false
-          has_coerce_method = false
-
-          match.each_pair do |first, second|
-            has_coerce_method ||= grape_coerce_with?(first)
-
-            if grape_type_def?(first) && grape_array_type?(second)
-              is_array_type = true
-            end
-          end
-
-          if is_array_type && !has_coerce_method
-            add_offense(node)
-          end
-        end
-      end
-    end
-  end
-end
diff --git a/spec/requests/api/settings_spec.rb b/spec/requests/api/settings_spec.rb
index 95d64ee81245e..07e7a48d8c4e5 100644
--- a/spec/requests/api/settings_spec.rb
+++ b/spec/requests/api/settings_spec.rb
@@ -60,14 +60,14 @@
             default_projects_limit: 3,
             default_project_creation: 2,
             password_authentication_enabled_for_web: false,
-            repository_storages: 'custom',
+            repository_storages: ['custom'],
             plantuml_enabled: true,
             plantuml_url: 'http://plantuml.example.com',
             sourcegraph_enabled: true,
             sourcegraph_url: 'https://sourcegraph.com',
             sourcegraph_public_only: false,
             default_snippet_visibility: 'internal',
-            restricted_visibility_levels: 'public',
+            restricted_visibility_levels: ['public'],
             default_artifacts_expire_in: '2 days',
             help_page_text: 'custom help text',
             help_page_hide_commercial_content: true,
@@ -89,9 +89,7 @@
             push_event_hooks_limit: 2,
             push_event_activities_limit: 2,
             snippet_size_limit: 5,
-            issues_create_limit: 300,
-            disabled_oauth_sign_in_sources: 'unknown',
-            import_sources: 'github,bitbucket'
+            issues_create_limit: 300
           }
 
         expect(response).to have_gitlab_http_status(:ok)
@@ -129,8 +127,6 @@
         expect(json_response['push_event_activities_limit']).to eq(2)
         expect(json_response['snippet_size_limit']).to eq(5)
         expect(json_response['issues_create_limit']).to eq(300)
-        expect(json_response['disabled_oauth_sign_in_sources']).to eq([])
-        expect(json_response['import_sources']).to match_array(%w(github bitbucket))
       end
     end
 
diff --git a/spec/rubocop/cop/api/grape_api_instance_spec.rb b/spec/rubocop/cop/api/grape_api_instance_spec.rb
deleted file mode 100644
index 0199377f104d6..0000000000000
--- a/spec/rubocop/cop/api/grape_api_instance_spec.rb
+++ /dev/null
@@ -1,31 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-require 'rubocop'
-require_relative '../../../support/helpers/expect_offense'
-require_relative '../../../../rubocop/cop/api/grape_api_instance'
-
-describe RuboCop::Cop::API::GrapeAPIInstance do
-  include CopHelper
-  include ExpectOffense
-
-  subject(:cop) { described_class.new }
-
-  it 'adds an offense when inheriting from Grape::API' do
-    inspect_source(<<~CODE.strip_indent)
-      class SomeAPI < Grape::API
-      end
-    CODE
-
-    expect(cop.offenses.size).to eq(1)
-  end
-
-  it 'does not add an offense when inheriting from Grape::API::Instance' do
-    inspect_source(<<~CODE.strip_indent)
-      class SomeAPI < Grape::API::Instance
-      end
-    CODE
-
-    expect(cop.offenses.size).to be_zero
-  end
-end
diff --git a/spec/rubocop/cop/api/grape_array_missing_coerce_spec.rb b/spec/rubocop/cop/api/grape_array_missing_coerce_spec.rb
deleted file mode 100644
index 8252e07837dbc..0000000000000
--- a/spec/rubocop/cop/api/grape_array_missing_coerce_spec.rb
+++ /dev/null
@@ -1,64 +0,0 @@
-# frozen_string_literal: true
-
-require 'fast_spec_helper'
-require 'rubocop'
-require_relative '../../../support/helpers/expect_offense'
-require_relative '../../../../rubocop/cop/api/grape_array_missing_coerce'
-
-describe RuboCop::Cop::API::GrapeArrayMissingCoerce do
-  include CopHelper
-  include ExpectOffense
-
-  subject(:cop) { described_class.new }
-
-  it 'adds an offense with a required parameter' do
-    inspect_source(<<~CODE.strip_indent)
-      class SomeAPI < Grape::API::Instance
-        params do
-          requires :values, type: Array[String]
-        end
-      end
-    CODE
-
-    expect(cop.offenses.size).to eq(1)
-  end
-
-  it 'adds an offense with an optional parameter' do
-    inspect_source(<<~CODE.strip_indent)
-      class SomeAPI < Grape::API::Instance
-        params do
-          optional :values, type: Array[String]
-        end
-      end
-    CODE
-
-    expect(cop.offenses.size).to eq(1)
-  end
-
-  it 'does not add an offense' do
-    inspect_source(<<~CODE.strip_indent)
-      class SomeAPI < Grape::API::Instance
-        params do
-          requires :values, type: Array[String], coerce_with: ->(val) { val.split(',').map(&:strip) }
-          requires :milestone, type: String, desc: 'Milestone title'
-          optional :assignee_id, types: [Integer, String], integer_none_any: true,
-            desc: 'Return issues which are assigned to the user with the given ID'
-        end
-      end
-    CODE
-
-    expect(cop.offenses.size).to be_zero
-  end
-
-  it 'does not add an offense for unrelated classes' do
-    inspect_source(<<~CODE.strip_indent)
-      class SomeClass
-        params do
-          requires :values, type: Array[String]
-        end
-      end
-    CODE
-
-    expect(cop.offenses.size).to be_zero
-  end
-end
diff --git a/spec/rubocop/cop/code_reuse/worker_spec.rb b/spec/rubocop/cop/code_reuse/worker_spec.rb
index 9005b5a0611f0..97acaeb7643e9 100644
--- a/spec/rubocop/cop/code_reuse/worker_spec.rb
+++ b/spec/rubocop/cop/code_reuse/worker_spec.rb
@@ -31,7 +31,7 @@ def index
       .and_return(true)
 
     expect_offense(<<~SOURCE)
-      class Foo < Grape::API::Instance
+      class Foo < Grape::API
         resource :projects do
           get '/' do
             FooWorker.perform_async
-- 
GitLab