{"id":13879021,"url":"https://github.com/TrueCar/graphql-decorate","last_synced_at":"2025-07-16T15:30:34.208Z","repository":{"id":40524196,"uuid":"342649050","full_name":"TrueCar/graphql-decorate","owner":"TrueCar","description":"Easily decorate graphql-ruby types with a flexible API","archived":true,"fork":false,"pushed_at":"2022-08-16T17:23:32.000Z","size":113,"stargazers_count":13,"open_issues_count":0,"forks_count":6,"subscribers_count":14,"default_branch":"master","last_synced_at":"2024-11-16T05:32:00.358Z","etag":null,"topics":["decorator-pattern","graphql","ruby"],"latest_commit_sha":null,"homepage":"http://truecar.github.io/graphql-decorate","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/TrueCar.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.txt","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-02-26T17:24:37.000Z","updated_at":"2024-11-04T16:01:02.000Z","dependencies_parsed_at":"2022-09-13T08:21:38.117Z","dependency_job_id":null,"html_url":"https://github.com/TrueCar/graphql-decorate","commit_stats":null,"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TrueCar%2Fgraphql-decorate","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TrueCar%2Fgraphql-decorate/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TrueCar%2Fgraphql-decorate/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/TrueCar%2Fgraphql-decorate/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/TrueCar","download_url":"https://codeload.github.com/TrueCar/graphql-decorate/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":226138849,"owners_count":17579496,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["decorator-pattern","graphql","ruby"],"created_at":"2024-08-06T08:02:07.137Z","updated_at":"2024-11-24T07:31:29.342Z","avatar_url":"https://github.com/TrueCar.png","language":"Ruby","funding_links":[],"categories":["Ruby"],"sub_categories":[],"readme":"[![Gem Version](https://badge.fury.io/rb/graphql-decorate.svg)](https://badge.fury.io/rb/graphql-decorate)\n![CI](https://github.com/TrueCar/graphql-decorate/actions/workflows/ci.yml/badge.svg)\n\n# GraphQL Decorate\n\n`graphql-decorate` adds an easy-to-use interface for decorating types in [`graphql-ruby`](https://github.com/rmosolgo/graphql-ruby). It lets \nyou move logic out of your type files and keep them declarative. \n\n## Installation\n\nAdd this line to your application's Gemfile:\n\n```ruby\ngem 'graphql-decorate'\n```\n\nAnd then execute:\n\n    $ bundle\n\nOr install it yourself as:\n\n    $ gem install graphql-decorate\n\nOnce the gem is installed, you need to add the plugin to  your schema and the integration into \nyour base object class. \n```ruby\nclass Schema \u003c GraphQL::Schema\n  use GraphQL::Decorate\nend\n\nclass BaseObject \u003c GraphQL::Schema::Object\n  include GraphQL::Decorate::ObjectIntegration\nend\n```\nNote that `use GraphQL::Decorate` must be included in the schema _after_ `query` and `mutation` \nso that the fields to be extended are initialized first.\n\n## Usage\n\n### Basic use case\n```ruby\nclass Rectangle\n  attr_reader :length\n\n  def initialize(length)\n    @length = length\n  end\nend\n\nclass RectangleDecorator \u003c BaseDecorator\n  def area\n    length * 2\n  end\nend\n\nclass RectangleType \u003c BaseObject\n  decorate_with RectangleDecorator\n  \n  field :area, Int, null: false\nend\n```\nIn this example, the `Rectangle` type is being decorated with a `RectangleDecorator`. Whenever a \n`Rectangle` gets resolved in the graph, the underlying object will be wrapped with a \n`RectangleDecorator`. All of the methods on the decorator are accessible on the type.\n\n### Decorators\nBy default, `graphql-decorate` is set up to work with [`draper`](https://github.com/drapergem/draper) style decorators. These decorators \nprovide a `decorate` method that wraps the original object and returns an instance of the \ndecorator. They can also take in additional metadata.\n```ruby\nRectangleDecorator.decorate(rectangle, context: metadata)\n```\nIf you are using a different decorator pattern then you can override this default behavior in \nthe configuration.\n```ruby\nGraphQL::Decorate.configure do |config|\n  config.decorate do |decorator_class, object, _metadata|\n    decorator_class.decorate_differently(object)\n  end\nend\n```\n\n### Types\nTwo methods are made available on your type classes: `decorate_with` and `decorate_metadata`. \nEvery method that yields the underlying object will also yield the current GraphQL `context`. \nIf decoration depends on some context in the current query then you can access it when the field is resolved.\n\n#### decorate_with\n`decorate_with` accepts a decorator class that will decorate every instance of your type.\n```ruby\nclass Rectangle \u003c GraphQL::Schema::Object\n  decorate_with RectangleDecorator\nend\n```\n\n`decorate_with` optionally accepts a block which yields the underlying object. If you have multiple \npossible decorator classes you can return the one intended for the underling object.\n```ruby\nclass Rectangle \u003c GraphQL::Schema::Object\n  decorate_with do |object, _graphql_context|\n    if object.length == object.width\n      SquareDecorator\n    else\n      RectangleDecorator\n    end\n  end\nend\n```\n\n#### decorate_metadata\nIf your decorator pattern allows additional metadata to be passed into the decorators, you can \ndefine it here. By default every metadata hash will contain `{ graphql: true }`. This is \nuseful if your decorator logic needs to diverge when used in a GraphQL context. Ideally your \ndecorators are agnostic to where they are being used, but it is available if needed.\n\n`decorate_metadata` yields a `GraphQL::Decorate::Metadata` metadata instance. It responds to two \nmethods: `unscoped` and `scoped`. `unscoped` sets metadata for a resolved field. `scoped` sets \nmetadata for a resolved field and all of its child fields. `unscoped` and `scoped` are expected \nto return `Hash`s.\n\n```ruby\nclass Rectangle \u003c GraphQL::Schema::Object\n  decorate_metadata do |metadata| \n    metadata.unscoped do |object, _graphql_context| \n      { \n        name: object.name\n      }\n    end\n   \n    metadata.scoped do |object, _graphql_context|\n      {\n        inside_rectangle: true\n      }\n    end\n  end\nend\n```\n`RectangleDecorator` will be initialized with metadata `{ name: \u003cobject_name\u003e,\ninside_rectangle: true, graphql: true }`. All child fields of `Rectangle` will be initialized \nwith metadata `{ inside_rectangle: true, graphql: true }`.\n\n#### Combinations\nYou can mix and match these methods to suit your needs. Note that if `unscoped` and \n`scoped` are both provided for metadata that `scoped` will override any shared keys.\n```ruby\nclass Rectangle \u003c GraphQL::Schema::Object\n  decorate_with RectangleDecorator\n  decorate_metadata do |metadata|\n    metadata.scoped do |object, _graphql_context|\n      {\n        name: object.name\n      } \n    end\n  end\nend\n```\n\n### Collections\nBy default `graphql-decorate` recognizes `Array` and `ActiveRecord::Relation` object types and \ndecorates every element in the collection. If you have other collection types that should have \ntheir elements decorated, you can add them in the configuration. Custom collection classes must \nrespond to `#map`.\n```ruby\nGraphQL::Decorate.configure do |config|\n  config.custom_collection_classes = [Mongoid::Relations::Targets::Enumerable]\nend\n```\n\n## Development\n\nAfter checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to \nrun the tests. You can also run `bin/console` for an interactive prompt that will allow you to \nexperiment.\n\n## License\n\nThe gem is available as open source under the terms of the \n[MIT License](https://opensource.org/licenses/MIT).\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTrueCar%2Fgraphql-decorate","html_url":"https://awesome.ecosyste.ms/projects/github.com%2FTrueCar%2Fgraphql-decorate","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2FTrueCar%2Fgraphql-decorate/lists"}