diff --git a/.rubocop.yml b/.rubocop.yml
index bd19b80e8b56a2805e537e25722377cc56285ef3..300cfe3d74c162fed6374e7825f853a0cc77d800 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 dbde17da603a290ce15b425beabdcd948bd1a5c0..c6dab495cbd07bf2d58a4b54df3db4f8e38bf3bb 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 3d6472a284d4710a44486ff58dcdef9705302787..be587ef2b5de3eed9c7a07e4955642996d09a990 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 4aec45c94291b8c74f1eb876660a92bccfd0f1de..0000000000000000000000000000000000000000
--- 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 a9ce1bc066ea33984182b6211881a557c514c8e7..25c8cbd3fde9295f2999e3040badc6e228938c16 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 1d03e93ab792fe7040b8b9491b5b53e50de11b59..c9fd1b75606d861c8efc47ab7b9b55a4fec51658 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 b84291e26be4df1cc24acc90e94098042fd84880..2e87935d51e0fe253410717ffb7a7ea73c44b7f5 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 037f89fadbe39ed3e09570930660b36aab93482e..8d1306b35a1c038968e5c9f88703eb4061fe3800 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 85779cc2bcd3974dfb14f639a3077f757e36c75e..eee4f2eb5f8b64cf007ea0ccc1df4d0dd16efe6f 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 afc45df21b94bdc8b3592fb96931d816cd740d00..d65c0bdb75161b9ef076f3c8577c002586e23b1c 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 bf87cf2e391a4d909a44862cbd7ea7ddae4cda0d..395a39c9d380267d2887241fee7c60546ccf4172 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 1f6359ac65b94a9cf03a8a58561424c0370dada5..f3a11bb1366e3ebbadbb0d9a7fdab1216d1805c1 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 d1bc4d2c379b7a966b131ad300fbb0dccc3f1a42..9ca425d6c0e08e9ce4ff39c1e76492470d7748ca 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 98934edbff6591c44acadc4feb9ceff9c767560b..a37954919e054e01b1a222ab07e1482ba38b5d8e 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 8f91d4818c27dce5038f7c902ddf76d9c93fe400..5e0de5aec9c9db4b6712233d1c925c85d06ef8c5 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 08d3f824c77fb96b080e45ecb8dcad2ff05a87e3..50c725c2e4a6146a211d55fc2cc5b4e279d8e05b 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 b70492687ee63b3ff03c5dc8d170550f7058889c..5be09b6017796b06f3aae8e0023c1190e5dc7342 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 1dd457d848538c71e3d82db0898656b0115c60fe..d3b59c6ede8c742111e07fe22ae2682f93370b0b 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 c09100b5b5fc25a3e72be6ba0ad30d47a5ee8ec1..460527b9da51a0bd253d3ba351975dab3c505314 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 78dbe57e9629ebf99caf4979d14d181bb91b6708..0bc78bdb0469302c6330a9b8f95abc5d92d8fe68 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 134414dbaeefc12cf93b6a9e6a4b5d3cd21d8a24..59cb0984ae28456cdbf1063f525de3164edac0de 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 a49085c3665e871670f7537c43c5f7a9d6c953ab..82089ca28606cd91fe7d5d5a08ffd271ff686350 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 a726b6d1b3b0fd7d592e4d2317c7aa22e4852b3f..212a0219a4c2875b760ab3a6cfc11fd072d7aa16 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 1da1b99242b9980b99c3e41d90683ff9b18a2dc8..13fbb77d3aea4e98c4ecb2728d8feba26fc91f79 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 0393dcdf9a234abe949f4216148d0a8cec115c65..0c1be8abf98a773f0dadfef3ea0d392b8dc42f17 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 a12cb75c60339e21069e36808c7c12e58c1077f9..3e43e7c27fd7f78759844415373d64618f14f8fe 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 79a37f0e5e3ce599c3d3cbcaa1b52d4913bb237e..4769f8ef86576c6ef2452730fca7312c56dbfd41 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 980fda44e5e8d2c4fe2ed484a06cf8217999433e..2695399b5af55489090a37d95179c2535afe76f4 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 19763a41dc83f8d1b35e8768f8f937ce0e21b3ca..9a82a2c1ff1c1b710fafec65c91fd741950276e5 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 1bc234576bc52d32897ddd50919ad0921e40d470..0682effccfd1f70661d1b88c74daffa341bda9c5 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 899b14bc9ac246abf39b786cc2e1274c77477fbb..807471382b7fd2d50e0ed3adb2c178bf99e051a2 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 069369a4014b189aa9ad480bdd7da1edcccf091b..07d9487e95751c6410cbb04cf98136433f0aab20 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 d314695bfa15e66e8eb5facc1414b0d0ff022407..a959f9a601352de78baf1e04cb3c32c0bc50d414 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 a759a25244a43a9adba4bf636d9820f69845ec06..0d5fe796401468e6f88d70bd11583a1ee2d7b3da 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 63df464083153e80b5111a07a38d8860fcf31208..d2122a3a8e588c2a7232bd6e69800454b968614e 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 391367d226828f1f5a49f853b0b10d408328f5d7..a3150e1f19f3cb7262e242fcfb9296d066302b8b 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 670bc2cad1cc7252d41d292203bc163f8987ad86..a7413d054addf453d34462ff1bfd817180e0c1be 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 69ba78c55882ae50bfbce123718f0cfc98d15673..e82a4fa7631499f00523f3ae5ff8d52526a1660d 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 fba4fbbca9c303c8c9804d13aa11a87dccbac6c7..8e346b4c658399f8327de989bc32bea05641b650 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 1f8ebf442f050b81228dd0d10d6dd1af00ec89fc..2e7a26870d6fdfe47592b89d0599360717308442 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 30d9d704a3de871d1f5ad73037f81fabffd0042e..dbd0ccb753b0da6fe5f48152148030affec1c477 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 3aa5f48cc22fc28ffa769b14ac609a462ca8a733..306f9cc147d0a0feabfe46044dd581406c2a990f 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 81ea3d0b889fd05e80a23c57727e10e0ea737ec0..14c5d3acca161ec5a6af25236961602622ed1388 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 0c25c70935a608d0a937dae6accb43cf55add576..e7d8617afeb50d5a08d38dfffc6f526b191d01b3 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 7a3cc1dba7d81843cdc886b2515d7f35ea95324c..ed66fce5977cf3d973feac878e74942b2748fadf 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 6de0ce19d9183b7bfdf7460e95498ec039d73b93..23c92ed7391c0be0939bfe2c0cbb72e8d686e0bf 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 1dc8a569cce1b6f28e1b814bce5b3d1eb1fb38f7..12be25ac7cddeefa8bf2bbd92cb560a6b602b783 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 102cd47818100430f7ba0b6257f34a08d6114286..8590fe7e3899ab4f12d6db30ed052e2ba76de0ca 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 4adb693b5681f7143a3aaec258889bb8aa31a062..878ee0aa0ff0954f25b4b8794b212e7a18c94553 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 c477cbb663e7cb7fe0b86e4b3dfa48a603347da3..2fe5ef45f7ff7c58c80a00801c7d9b943e2d2f7e 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 86fdf3342271ceb8306c133fb9c6527deecd1efe..76ae44fa4052d483d8663479bd1569d8514734f5 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 60e1ca10a2f1ac2bbdd23ef527247a69415541be..7f204735a3dccbce67329f1b36aeb0575c911eba 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 de9d7169dc0e2930b060562ad25802bb1ddb8498..38256a87abdfd50b40f16174a2c7896c6b635f31 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 c44655419885b7003e64d7b7c81224447959ceee..611ad21f077ebaf57dac02fb72dfd8a755309154 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 59b0458fd98acfe00a49254fc42ace5272f147e5..ddcd99ece1fd99673e267d7f6562f060f9543723 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 60495ea8701839c16881656df7df2c274bd29f7b..6b62a086960a74f5058c75dedfd9bca21c044840 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 44c5ba107ff00b9dc0d6ee72feea0987a1607e3f..1206fda0383fe03ce384b6e2813b4db9fb93bd48 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 625748cbfdf1c5c856601ab83479a64a26c906d5..1857c56cee3f6f1f12e00539a8e817e284d68b09 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 ed7ab18c869850516f9746940f6248aad9f1a245..61e57effd59ac71fdee548735d9ea76f453bf330 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 49b69ae8fe990e678e1517bd0db4fb9fbc184d82..5f9c4014bb2eff63e49162bc75029a0555ad042f 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 ac37240afe5bad2f50e63213db9e30bc490daa78..d96348d5b987eb6dbd0458b6e82f040794cac505 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 952e227ab7789003d4f09106bef3e1a547619036..c7e3ad79ed39c110d22b46f65a54b49674a40aea 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 69547fcacdf47cd8074fdb5c52d8bf5f07223554..be100fa9dac1aa425620dab05268628b4202a0f8 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 c791ffa541f555d0d92ef42b75489b108bae363f..44bc93a57dd180360db03b6c018bdb0340d9dad5 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 5305b25538f896efe0747b9fe5a282aad271210c..ee8dc822098c2bdf9d5b7f46aed07854e4ee8afb 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 f4c84f2eee80a1743dbde184ec0c4509b48c0386..a700bea0fd79d652e329cc61be78d7dbc3646d82 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 6019a8991f38512a33b2c2383762e5bf75ea3910..de9a3120d9026663f44b430d05f3ff755973ac43 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 cb83d22a07f1e18ca45deb96c36c4eba301466e5..9dd2de5c7ba3e12bdbbd9c8c9f8ca07eeaba49b2 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 8a46ebf4ef4a6e0fe94a5a1efdbe32e0f5dbce22..a775102e87d8c8b6267d28ad5eee8ab99599aa04 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 4e8d68c8d094c875df4cdac1b41d0d74afe4abab..70e6b8395d76751274261ef5a78de01344f09bfc 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 9501e777fffec2999ddfb819edf92382d92a68a5..0f14d00306592e23b788d986414107c925483587 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 0a3df3ed96edc44897e61d1036c74931dbde9792..8e3b3ff8ce5efea70613cd782756cc0c16fc43f9 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 f6cd3f83ff386756c5e63f4e5803af80949fdfd1..d2152fad07baa494f041b492ba5fa4765ed002bc 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 1f5086127a81cdb441c5e90dce54d8bb42d05fb4..87818903705fdd1ecb5241948f613dc928ee2cc5 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 4c8e4b7a1164148a1dcd01408a5b128f3ec56e44..999bf1627c187ac7f9762a344bf5b515d5c00f59 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 dcf950d7a035bbb49ee1f7336b47e686c5c6cef1..42e7dc751f08f59989438b2565c0d9f298556095 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 a34ac5b0169e29d50ac4891ce6910d03dfe767cb..b4c5d7869a22417e377069236f49ef74481f05b1 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 1a0fe393753dc0225724fb732aa88aebe6cd9dc4..086a1b7c402472508bc24bcb89334c8a6f303859 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 0b7c35cadbd4a20940cf954fdde652eb2d732db1..6d93cc65336138558f987f5b520e7dedcd65075d 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 def479ba99b0fef37f28ad33c95f73fc0310cbc5..e86bcc19b2b07f80ed4ff62383c20cb2fc01efb9 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 c088c71cde7a551d9a585e3977c53d558aac7330..f3a08ae970ada195fe3f6a71ee8f6a1345c98ed4 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 87144fd31cca289f4a23c30985706652e40d32bb..cb1dca11e87265e4585fc9d502e4f4fd32f06957 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 4e71e4c50de22c391c213367221efb74d90c7c40..0dd1850e526b7b4eb004a0f362472b6f9f089873 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 b825904e2c5f1fc4565d66d2fc49140a0ab9a6fb..28019ce77961dc0020292767ba17053eac05b072 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 64ec6f0a57a6fda42e7cb808da09cddea72d08c4..14888037f53972900967afec15342fc47a8d6c4c 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 0b79431a76dd771d06a92ce495f6c573b9d8c34d..e4c017fab42b923b8269b34f67dee6454d4e48e1 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 181c2fd4a6f7c319032408a0846f723e0c19ef48..69b751e9bdbe19374731c292e7da1601aa6b39c6 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 1e2f0e011eda434672d0941f739f5ac365d9182e..76ab9a2190bda28c429433bfa07ab540460d10bf 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 7efc12121d24c0727341f631520cec8407809fc6..88d04e70e1191d44c5016161eaa05d88225dd785 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 c6d10f22bb450b0e86086371dbb2685f47f9a48a..2c12c6387fb602cb54adf79f7e04e32a178c266d 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 d924d717c8552346ffc1f4024a80dff1c84bf6fd..7f95b411b3673ad73b789d691e15d98d846bd459 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 b5933ca4b940f7268dfef1887f1fa5d22e878c18..8ca5dfa082ece53943633f6d288d1a65c2590e8d 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 a20523fd55f260fc50aaaad6df308a067fe518e3..ed52506de147c1a2fa5bfafbd8943b4fda4ed60a 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 56f2b769464f469c6d6fbb447515e0d9895ec975..7585293031f0fd5d6e7fd37174232f1c9d342212 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 05dc417e3b173d1a9dd7ea71f885491a9481a4c6..9e9f510128558e03b0d884e06b73aba9673ebc31 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 7cf7584bf4c4d4073916187fcfdd389ac44bb5b0..916f89649a5ff2b8a0d06d4dacd7a4e1da6c33e9 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 7f42d8ed0d9180167521e623287fde33b0d96666..d375c35e8c0c41f0f31da776c93925d08778c922 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 00430fa08c6558ed45f36ed216c99f5b8add512f..73711a7e0ba15b05a15617e089aff2d605a64d3c 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 b80d662f117ce532cdef035b18606e366859ebd6..14c83114f3273c8fc3be983c0aea1d3f69a2ea53 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 986827e80be255ad10776b570c1b474b9fbbaac1..21d4928193eec218b0d92296192a72b83e028770 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 eab8ba25410ca7a477163e3ccb07a0e654e2dfca..564a00701c47323082f581423ba64809f1003253 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 5f8d23f15fa4d381fe7d14890bf5eeee38d8f652..6c8da414e4db7578c6a43367ee1e49902d703f81 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 9ef1561f4237ea15865898e7407fba7e530923a7..f27afd0055f5023d03622437046f0bb6cbfc27e8 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 321c14de1b932e0d754c2338eade1c7a8f965a73..920938ad453b77573d5dab25f9c6be5efe4b0fbf 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 7a7dfcedecb4b3eab44b1ef2678b174babba4fff..59f0dbe8a9b739f32ca595d794a1093c4df41510 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 c014641ca043ec0eb25c866445045fe2c45fdff2..b730e02706387819f558d1c6cb12c8d81fc49b2e 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 edf4a8ca14eaca1ad6fecc57146d6910a29c5eac..2b283d82e4aec11dc839727e6d5264d6faa2d20c 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 f7796b1e9694d8d4b0eaf681f793ca4e43ee6515..a7672021db01bae754b05264fc35f8fc33456c56 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 338d6c533a4b19ec868ad2585b43330ef777089d..a673ccb4af040a0aeed9ea623c4f7793de36c159 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 a0822271cca51da3536d874665fa94b3158f638a..de77bef43ce90616bf4409ebf4571f3975d21173 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 2254a0b78988c06abd55808104bfdd3e62e4545c..37d4ca29b684e242932bd1c1d9e83b6c5b4ea82e 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 3e43fe8b257c1fc8eff59efe2585313a87e71212..6ad30aa56e0f549fc722bc7674d0c0314921ffde 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 b7bc936fe2fffde6dc7f2293c8ebf08b5ef5a39c..d45786cdd3d7820c3caa343789920454e1504fd3 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 d71a4e9d736a20b28a17ff5278bdcc3fa132ac0d..432fa3ac0c92c0fbd71a130362da7a48ae723c1f 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 8ff885983bccd523d9d1665e0e037acb56ef5a2e..62e159ab0034a327aad503533e014f6a09b85b1d 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 e1f279df045a7dfbbfb3f6a62f67385496894a1f..e40a5dde7ce7df697b697adbbf9058268ca51365 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 4fb7bffb3d55cc81c20fa601c5b2ddf14541187c..3eafc1ead77bd1ca2c9e27b8661c8edc91ac05b2 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 f8b621c1c38452bdf8af943aa6f8d82f0ca4ea48..8cb46bd3ad6a1a6c20dffe50545828c2762f4b3f 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 79a6b527581ea120fd5a5dcb62f83967688fa289..ee7fe669519aaf67cbaa0c13aa8146c92a5c067b 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 7d27b575efa20b1e053a141a24256f6f9de612d0..4c3d2d131acf38274924dd00032f573f8d131ee4 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 a232b58d3f7efbdbcad06a889a55cf5cc14cceea..ae03595eb25ebc779cb209cee66e9f2de08c0853 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 46058f45bcba1e9e0d5771e646c399ba013deeed..edc99590cdb2789c3cf839730537ec68f4d5e8fc 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 f881d5b63e66fd75b0864a94cf711d20dfe943a7..06f8920b37cfade84428978bb23a3de7214e5fd2 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 e1dfb647fa08df0d18341bfeb82acc28a45f7136..299301aabc46cc8959c37c13ee38270d6388d260 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 ed15bd92f1b93a359d424e8e1b56d0752bd3c055..555fd98b451f2136c356dcc277c3d9dd784bda55 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 726e693826e3c6f0e9810e25b7b26179d6a0084a..734311e1142dde915ff08be30c560ac6bd3868e6 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 797c6097b042247d36ccc3d7150e730c4c2626f9..9fd9d13a20c2a65ab2b2f399dba59bcf09736b5d 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 7cea44e63049ce3ca4cc439784fa0078e328b675..0e7576c9243c78d4c0e38237878e6cd60d5f02cf 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 9be192a80e01a40535f2c0666ba33523c9c14bb5..0e83686cab2d4f72a292ce2026105eccde2ec0a6 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 71388fd500a40cf548817eec430626cbc1092769..8643854a655b1ddc0e41db778fea42494d13142a 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 360000861fcc4194069c3373868d5d05187f8b9c..175fbb2ce928bfbbae5fe67f3d299893827b9cb8 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 c3e4c806a597abfef818f514203986349c768e97..f5ca2f4d5a1a3313675b5424dad13fd0dbac0b7b 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 2196801096fcd8675ca19a6a4596c3b06c1e3011..14ee0f75513cde413d2c207cc25c3914a892f2c3 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 3eded5606c1996b718c4cfbe1a5e7d41796b54f4..119902a189c774139bc78e164cc32ddeff35f80c 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 7c98a749bf7e8fc2b3e31e3b4310a5444eeb2fa7..ee0731a331f9698cd5b966110d6c565d1bb213b5 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 b0a7f898eeca1a2c64b31434b93d6a0b64b969f2..1fd86d1e72075bc51c20a2db4fccac55cf8b005f 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 aaa31cb7cc6c7a07fd52c269028ab3d163a3433e..ee13473c8485e9e4ff27342bc1170d56ad0f0c3d 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 16154aac7b5e164c3280bbed362acac5b1ff457e..f72230c084c5beee8c6afa98aa714f60f000b13e 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 ae11561205e7783effdab4b7f7ea2fa24dd441f9..95b3e90323c651a1876b43df4dfa02bd0e3b63f9 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 ef83d8de151d65950bbd7a72d8b6b2a927bd6a94..7e484eb888516d3d51e55b8c47a2621e2866d4bc 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 37f134dcffa0129853396ddba1c07b59f98b7fc8..0b2df85f61fc284a1743e46315e08747723b5f4d 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 60bcee094ad78002dae28c989ce5d15475d42487..f7f7c881f4aa8f83107de18f97952d57e02d3586 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 aac261757157d3b563ee575350ea8706b45498be..9095aba7340f27aae485a32016683b101782959e 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 f1adc9e5aff4edf1be6f5e205afca16629d2c391..43ee1dd1f71e2279b37d930f32675c087946a059 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 e685f2c4afea2adb8dde320ebbb405d21cde92bd..ed52a4fc8f2478ce32248099b3739377232afa1b 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 9ee1822339c8c368fe37151852a576fb37ef5f80..5fd5c6bd9b094bc3d18c8d0cb436bf2f58162491 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 0849a0ff9452c60a3f2c84c69c1494b242b50669..09644d42e8f48c5f4b617e3955ae8564a917dad7 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 de1373144e373093ed288f2b33223c9c772f5c44..693c20cb73aa36922162c7e4198cc65527c95b57 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 905b1c4d52b6a614be940778580327647b56aaeb..b89de93af1bbe380be5edd336bc45fa0a45e40b9 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 3869fd3ac76529f2c9eaee28047a6f5b27a61a67..d2dce34dfa5b9a4e98e179027c36fbc026d7a596 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 34d21d3d7d86e299a160c5288e14ef37bc9e2232..72d7d9941020ac6cbe749c8703d5a1af9fd08f4c 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 533663fb087efd0640536fae453ba4a7e7e27342..dfb54446ddf31c1d38b24f76ef04ff5094b0b29d 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 cf951ba497e5df52f36d1ef5bfbcde945cacefbf..d008d1b9e97f00ad2a6b1b47742f4a53999d70b2 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 d8e0a425625d9947b3264b9e8efbc863055320d4..51fae0e54aaca2cc9ff49ab9461694a610f29df6 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 c1fbd3ca7c6d2cc4eeade9ad525f9da628f1b529..796b14506022d181dbfb458a2aea23ab1fedbc99 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 80a97aae4296fb1af852ddc77aced95d76c22fab..51f357d94770a08c4f86e4eccd07f508e1db18ea 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 7192c33a41f3da1ee9cede8580bb635ffa96d575..5141d1fd499395a26c05e62fe749d8fbd409ce63 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 8a054adf3b828b8605b17804ef0a875b5a7723be..02b8bb55274f1ded55a0655f048558c6168177e7 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 8590487cf718c2c108df20e8490b04d16b13ac50..e1829403941d57232e6441e79fcfa6f31dfcd95d 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 90127ecbc73690d7477bbed85bcda6230f72ed67..8df4b381bbfecce3a552eb887fc3ca2cca53ea16 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 c46c3a45514d842ff9aaca4b98bab0ec4439b1b9..c986414c223c84f446ebbcec65b2599738322cc7 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 409eb67a3d33e6787090978920ce5639500e4595..b551878abd1a8138d3893346d52a4ab295b0ee9a 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 b8ab08b3fd4074605d491b6cfa03b076cc1933a0..0000000000000000000000000000000000000000
--- 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 0000000000000000000000000000000000000000..60277b99106ab87efe38cedabbb3f324bc8a5cc2
--- /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 0000000000000000000000000000000000000000..53b5790bfa21d4c6dd5dc4a9ef416f6ab62fdb42
--- /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 e65e94fc8db70c160ef1849b7fd57ecb9b4ac756..18d111f655615aa5227c72fdf89b86d68991aa1a 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 8740915caefe5065f8090947d7f1337b8247e964..192b06b8a1b06ba09c813a57ae8520af07a00461 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 6a480fc2bd90147c7f85caefe95f7afc71b2ef61..2d8c90260fa3056eac8a8ebf1e9bd085f1e2cbc3 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 e13b5d4f1c55bf2053ab6aa4d5bb318fdfb41084..a2146406690f3165bef73544658653c8de4390fd 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 de11b9ef3f6e18b1165097e556f8940d0e0b9dda..0000000000000000000000000000000000000000
--- 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 3d7a6a72d818b2643d0413f72fb5aadcbab53552..0000000000000000000000000000000000000000
--- 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 95d64ee81245ebf2bca1f13a6c62e227a0a8430b..07e7a48d8c4e575fd4aadbbc816b12dfdacfdf5a 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 0199377f104d669b363956f4a6f4d2936a1db085..0000000000000000000000000000000000000000
--- 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 8252e07837dbcc63d2045aa130c196898f80b3f9..0000000000000000000000000000000000000000
--- 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 9005b5a0611f0140063c3a44622c912155f20739..97acaeb7643e9c34d421766fe4079c16b0cae9fa 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