diff options
author | Bob Van Landuyt <bob@vanlanduyt.co> | 2018-05-23 10:55:14 +0300 |
---|---|---|
committer | Bob Van Landuyt <bob@vanlanduyt.co> | 2018-06-06 11:58:54 +0300 |
commit | 9b65d4bb417fb4939289eab94487c894f0a62db6 (patch) | |
tree | 1f97b9a1bd0d722a3c3ff4e89ec13bdb7a3aec00 /app/graphql/types | |
parent | c443133e779c4c508b9c6429dd4ba623d64f03f1 (diff) |
Initial setup GraphQL using graphql-ruby 1.8
- All definitions have been replaced by classes:
http://graphql-ruby.org/schema/class_based_api.html
- Authorization & Presentation have been refactored to work in the
class based system
- Loaders have been replaced by resolvers
- Times are now coersed as ISO 8601
Diffstat (limited to 'app/graphql/types')
-rw-r--r-- | app/graphql/types/base_enum.rb | 4 | ||||
-rw-r--r-- | app/graphql/types/base_field.rb | 5 | ||||
-rw-r--r-- | app/graphql/types/base_input_object.rb | 4 | ||||
-rw-r--r-- | app/graphql/types/base_interface.rb | 5 | ||||
-rw-r--r-- | app/graphql/types/base_object.rb | 7 | ||||
-rw-r--r-- | app/graphql/types/base_scalar.rb | 4 | ||||
-rw-r--r-- | app/graphql/types/base_union.rb | 4 | ||||
-rw-r--r-- | app/graphql/types/merge_request_type.rb | 87 | ||||
-rw-r--r-- | app/graphql/types/mutation_type.rb | 8 | ||||
-rw-r--r-- | app/graphql/types/project_type.rb | 88 | ||||
-rw-r--r-- | app/graphql/types/query_type.rb | 47 | ||||
-rw-r--r-- | app/graphql/types/time_type.rb | 18 |
12 files changed, 154 insertions, 127 deletions
diff --git a/app/graphql/types/base_enum.rb b/app/graphql/types/base_enum.rb new file mode 100644 index 00000000000..b45a845f74f --- /dev/null +++ b/app/graphql/types/base_enum.rb @@ -0,0 +1,4 @@ +module Types + class BaseEnum < GraphQL::Schema::Enum + end +end diff --git a/app/graphql/types/base_field.rb b/app/graphql/types/base_field.rb new file mode 100644 index 00000000000..c5740a334d7 --- /dev/null +++ b/app/graphql/types/base_field.rb @@ -0,0 +1,5 @@ +module Types + class BaseField < GraphQL::Schema::Field + prepend Gitlab::Graphql::Authorize + end +end diff --git a/app/graphql/types/base_input_object.rb b/app/graphql/types/base_input_object.rb new file mode 100644 index 00000000000..309e336e6c8 --- /dev/null +++ b/app/graphql/types/base_input_object.rb @@ -0,0 +1,4 @@ +module Types + class BaseInputObject < GraphQL::Schema::InputObject + end +end diff --git a/app/graphql/types/base_interface.rb b/app/graphql/types/base_interface.rb new file mode 100644 index 00000000000..69e72dc5808 --- /dev/null +++ b/app/graphql/types/base_interface.rb @@ -0,0 +1,5 @@ +module Types + module BaseInterface + include GraphQL::Schema::Interface + end +end diff --git a/app/graphql/types/base_object.rb b/app/graphql/types/base_object.rb new file mode 100644 index 00000000000..e033ef96ce9 --- /dev/null +++ b/app/graphql/types/base_object.rb @@ -0,0 +1,7 @@ +module Types + class BaseObject < GraphQL::Schema::Object + prepend Gitlab::Graphql::Present + + field_class Types::BaseField + end +end diff --git a/app/graphql/types/base_scalar.rb b/app/graphql/types/base_scalar.rb new file mode 100644 index 00000000000..c0aa38be239 --- /dev/null +++ b/app/graphql/types/base_scalar.rb @@ -0,0 +1,4 @@ +module Types + class BaseScalar < GraphQL::Schema::Scalar + end +end diff --git a/app/graphql/types/base_union.rb b/app/graphql/types/base_union.rb new file mode 100644 index 00000000000..36337fc6ee5 --- /dev/null +++ b/app/graphql/types/base_union.rb @@ -0,0 +1,4 @@ +module Types + class BaseUnion < GraphQL::Schema::Union + end +end diff --git a/app/graphql/types/merge_request_type.rb b/app/graphql/types/merge_request_type.rb index fc430ca03d5..d5d24952984 100644 --- a/app/graphql/types/merge_request_type.rb +++ b/app/graphql/types/merge_request_type.rb @@ -1,46 +1,47 @@ -Types::MergeRequestType = GraphQL::ObjectType.define do - present_using MergeRequestPresenter +module Types + class MergeRequestType < BaseObject + present_using MergeRequestPresenter - name 'MergeRequest' + graphql_name 'MergeRequest' - field :id, !types.ID - field :iid, !types.ID - field :title, !types.String - field :description, types.String - field :state, types.String - field :created_at, !Types::TimeType - field :updated_at, !Types::TimeType - field :source_project, Types::ProjectType - field :target_project, !Types::ProjectType - # Alias for target_project - field :project, !Types::ProjectType - field :project_id, !types.Int, property: :target_project_id - field :source_project_id, types.Int - field :target_project_id, !types.Int - field :source_branch, !types.String - field :target_branch, !types.String - field :work_in_progress, types.Boolean, property: :work_in_progress? - field :merge_when_pipeline_succeeds, types.Boolean - field :sha, types.String, property: :diff_head_sha - field :merge_commit_sha, types.String - field :user_notes_count, types.Int - field :should_remove_source_branch, types.Boolean, property: :should_remove_source_branch? - field :force_remove_source_branch, types.Boolean, property: :force_remove_source_branch? - field :merge_status, types.String - field :in_progress_merge_commit_sha, types.String - field :merge_error, types.String - field :allow_maintainer_to_push, types.Boolean - field :should_be_rebased, types.Boolean, property: :should_be_rebased? - field :rebase_commit_sha, types.String - field :rebase_in_progress, types.Boolean, property: :rebase_in_progress? - field :diff_head_sha, types.String - field :merge_commit_message, types.String - field :merge_ongoing, types.Boolean, property: :merge_ongoing? - field :work_in_progress, types.Boolean, property: :work_in_progress? - field :source_branch_exists, types.Boolean, property: :source_branch_exists? - field :mergeable_discussions_state, types.Boolean - field :web_url, types.String, property: :web_url - field :upvotes, types.Int - field :downvotes, types.Int - field :subscribed, types.Boolean, property: :subscribed? + field :id, GraphQL::ID_TYPE, null: false + field :iid, GraphQL::ID_TYPE, null: false + field :title, GraphQL::STRING_TYPE, null: false + field :description, GraphQL::STRING_TYPE, null: true + field :state, GraphQL::STRING_TYPE, null: true + field :created_at, Types::TimeType, null: false + field :updated_at, Types::TimeType, null: false + field :source_project, Types::ProjectType, null: true + field :target_project, Types::ProjectType, null: false + # Alias for target_project + field :project, Types::ProjectType, null: false + field :project_id, GraphQL::INT_TYPE, null: false, method: :target_project_id + field :source_project_id, GraphQL::INT_TYPE, null: true + field :target_project_id, GraphQL::INT_TYPE, null: false + field :source_branch, GraphQL::STRING_TYPE, null: false + field :target_branch, GraphQL::STRING_TYPE, null: false + field :work_in_progress, GraphQL::BOOLEAN_TYPE, method: :work_in_progress?, null: false + field :merge_when_pipeline_succeeds, GraphQL::BOOLEAN_TYPE, null: true + field :diff_head_sha, GraphQL::STRING_TYPE, null: true + field :merge_commit_sha, GraphQL::STRING_TYPE, null: true + field :user_notes_count, GraphQL::INT_TYPE, null: true + field :should_remove_source_branch, GraphQL::BOOLEAN_TYPE, method: :should_remove_source_branch?, null: true + field :force_remove_source_branch, GraphQL::BOOLEAN_TYPE, method: :force_remove_source_branch?, null: true + field :merge_status, GraphQL::STRING_TYPE, null: true + field :in_progress_merge_commit_sha, GraphQL::STRING_TYPE, null: true + field :merge_error, GraphQL::STRING_TYPE, null: true + field :allow_collaboration, GraphQL::BOOLEAN_TYPE, null: true + field :should_be_rebased, GraphQL::BOOLEAN_TYPE, method: :should_be_rebased?, null: false + field :rebase_commit_sha, GraphQL::STRING_TYPE, null: true + field :rebase_in_progress, GraphQL::BOOLEAN_TYPE, method: :rebase_in_progress?, null: false + field :diff_head_sha, GraphQL::STRING_TYPE, null: true + field :merge_commit_message, GraphQL::STRING_TYPE, null: true + field :merge_ongoing, GraphQL::BOOLEAN_TYPE, method: :merge_ongoing?, null: false + field :source_branch_exists, GraphQL::BOOLEAN_TYPE, method: :source_branch_exists?, null: false + field :mergeable_discussions_state, GraphQL::BOOLEAN_TYPE, null: true + field :web_url, GraphQL::STRING_TYPE, null: true + field :upvotes, GraphQL::INT_TYPE, null: false + field :downvotes, GraphQL::INT_TYPE, null: false + field :subscribed, GraphQL::BOOLEAN_TYPE, method: :subscribed?, null: false + end end diff --git a/app/graphql/types/mutation_type.rb b/app/graphql/types/mutation_type.rb index c5061f10239..06ed91c1658 100644 --- a/app/graphql/types/mutation_type.rb +++ b/app/graphql/types/mutation_type.rb @@ -1,5 +1,7 @@ -Types::MutationType = GraphQL::ObjectType.define do - name "Mutation" +module Types + class MutationType < BaseObject + graphql_name "Mutation" - # TODO: Add Mutations as fields + # TODO: Add Mutations as fields + end end diff --git a/app/graphql/types/project_type.rb b/app/graphql/types/project_type.rb index 593c1b67830..9e885d5845a 100644 --- a/app/graphql/types/project_type.rb +++ b/app/graphql/types/project_type.rb @@ -1,63 +1,65 @@ -Types::ProjectType = GraphQL::ObjectType.define do - name 'Project' +module Types + class ProjectType < BaseObject + graphql_name 'Project' - field :id, !types.ID + field :id, GraphQL::ID_TYPE, null: false - field :full_path, !types.ID - field :path, !types.String + field :full_path, GraphQL::ID_TYPE, null: false + field :path, GraphQL::STRING_TYPE, null: false - field :name_with_namespace, !types.String - field :name, !types.String + field :name_with_namespace, GraphQL::STRING_TYPE, null: false + field :name, GraphQL::STRING_TYPE, null: false - field :description, types.String + field :description, GraphQL::STRING_TYPE, null: true - field :default_branch, types.String - field :tag_list, types.String + field :default_branch, GraphQL::STRING_TYPE, null: true + field :tag_list, GraphQL::STRING_TYPE, null: true - field :ssh_url_to_repo, types.String - field :http_url_to_repo, types.String - field :web_url, types.String + field :ssh_url_to_repo, GraphQL::STRING_TYPE, null: true + field :http_url_to_repo, GraphQL::STRING_TYPE, null: true + field :web_url, GraphQL::STRING_TYPE, null: true - field :star_count, !types.Int - field :forks_count, !types.Int + field :star_count, GraphQL::INT_TYPE, null: false + field :forks_count, GraphQL::INT_TYPE, null: false - field :created_at, Types::TimeType - field :last_activity_at, Types::TimeType + field :created_at, Types::TimeType, null: true + field :last_activity_at, Types::TimeType, null: true - field :archived, types.Boolean + field :archived, GraphQL::BOOLEAN_TYPE, null: true - field :visibility, types.String + field :visibility, GraphQL::STRING_TYPE, null: true - field :container_registry_enabled, types.Boolean - field :shared_runners_enabled, types.Boolean - field :lfs_enabled, types.Boolean - field :ff_only_enabled, types.Boolean, property: :merge_requests_ff_only_enabled + field :container_registry_enabled, GraphQL::BOOLEAN_TYPE, null: true + field :shared_runners_enabled, GraphQL::BOOLEAN_TYPE, null: true + field :lfs_enabled, GraphQL::BOOLEAN_TYPE, null: true + field :merge_requests_ff_only_enabled, GraphQL::BOOLEAN_TYPE, null: true - field :avatar_url, types.String do - resolve ->(project, args, ctx) { project.avatar_url(only_path: false) } - end + field :avatar_url, GraphQL::STRING_TYPE, null: true, resolve: -> (project, args, ctx) do + project.avatar_url(only_path: false) + end - %i[issues merge_requests wiki snippets].each do |feature| - field "#{feature}_enabled", types.Boolean do - resolve ->(project, args, ctx) { project.feature_available?(feature, ctx[:current_user]) } + %i[issues merge_requests wiki snippets].each do |feature| + field "#{feature}_enabled", GraphQL::BOOLEAN_TYPE, null: true, resolve: -> (project, args, ctx) do + project.feature_available?(feature, ctx[:current_user]) + end end - end - field :jobs_enabled, types.Boolean do - resolve ->(project, args, ctx) { project.feature_available?(:builds, ctx[:current_user]) } - end + field :jobs_enabled, GraphQL::BOOLEAN_TYPE, null: true, resolve: -> (project, args, ctx) do + project.feature_available?(:builds, ctx[:current_user]) + end - field :public_jobs, types.Boolean, property: :public_builds + field :public_jobs, GraphQL::BOOLEAN_TYPE, method: :public_builds, null: true - field :open_issues_count, types.Int do - resolve ->(project, args, ctx) { project.open_issues_count if project.feature_available?(:issues, ctx[:current_user]) } - end + field :open_issues_count, GraphQL::INT_TYPE, null: true, resolve: -> (project, args, ctx) do + project.open_issues_count if project.feature_available?(:issues, ctx[:current_user]) + end - field :import_status, types.String - field :ci_config_path, types.String + field :import_status, GraphQL::STRING_TYPE, null: true + field :ci_config_path, GraphQL::STRING_TYPE, null: true - field :only_allow_merge_if_pipeline_succeeds, types.Boolean - field :request_access_enabled, types.Boolean - field :only_allow_merge_if_all_discussions_are_resolved, types.Boolean - field :printing_merge_request_link_enabled, types.Boolean + field :only_allow_merge_if_pipeline_succeeds, GraphQL::BOOLEAN_TYPE, null: true + field :request_access_enabled, GraphQL::BOOLEAN_TYPE, null: true + field :only_allow_merge_if_all_discussions_are_resolved, GraphQL::BOOLEAN_TYPE, null: true + field :printing_merge_request_link_enabled, GraphQL::BOOLEAN_TYPE, null: true + end end diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb index 029bbd098ad..be79c78bf67 100644 --- a/app/graphql/types/query_type.rb +++ b/app/graphql/types/query_type.rb @@ -1,38 +1,21 @@ -Types::QueryType = GraphQL::ObjectType.define do - name 'Query' - - field :project, Types::ProjectType do - argument :full_path, !types.ID do - description 'The full path of the project, e.g., "gitlab-org/gitlab-ce"' - end - - authorize :read_project - - resolve Loaders::FullPathLoader[:project] - end - - field :merge_request, Types::MergeRequestType do - argument :project, !types.ID do - description 'The full path of the target project, e.g., "gitlab-org/gitlab-ce"' +module Types + class QueryType < BaseObject + graphql_name 'Query' + + field :project, Types::ProjectType, + null: true, + resolver: Resolvers::ProjectResolver, + description: "Find a project" do + authorize :read_project end - argument :iid, !types.ID do - description 'The IID of the merge request, e.g., "1"' + field :merge_request, Types::MergeRequestType, + null: true, + resolver: Resolvers::MergeRequestResolver, + description: "Find a merge request" do + authorize :read_merge_request end - authorize :read_merge_request - - resolve Loaders::IidLoader[:merge_request] - end - - # Testing endpoint to validate the API with - field :echo, types.String do - argument :text, types.String - - resolve -> (obj, args, ctx) do - username = ctx[:current_user]&.username - - "#{username.inspect} says: #{args[:text]}" - end + field :echo, GraphQL::STRING_TYPE, null: false, function: Functions::Echo.new end end diff --git a/app/graphql/types/time_type.rb b/app/graphql/types/time_type.rb index fb717eb3dc7..2333d82ad1e 100644 --- a/app/graphql/types/time_type.rb +++ b/app/graphql/types/time_type.rb @@ -1,8 +1,14 @@ -# Taken from http://www.rubydoc.info/github/rmosolgo/graphql-ruby/GraphQL/ScalarType -Types::TimeType = GraphQL::ScalarType.define do - name 'Time' - description 'Time since epoch in fractional seconds' +module Types + class TimeType < BaseScalar + graphql_name 'Time' + description 'Time represented in ISO 8601' - coerce_input ->(value, ctx) { Time.at(Float(value)) } - coerce_result ->(value, ctx) { value.to_f } + def self.coerce_input(value, ctx) + Time.parse(value) + end + + def self.coerce_result(value, ctx) + value.iso8601 + end + end end |