Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support composite keys/inputs #139

Closed
gmac opened this issue Jun 3, 2024 · 0 comments · Fixed by #141
Closed

Support composite keys/inputs #139

gmac opened this issue Jun 3, 2024 · 0 comments · Fixed by #141
Labels

Comments

@gmac
Copy link
Owner

gmac commented Jun 3, 2024

It would add practical value if composite key selections were allowed. Composite keys would require an additional argument mapping to express how the composite selections map into query arguments:

input WidgetKey {
  group: String!
  name: String!
}

widgets(keys: [WidgetKey!]!, other: String): [Widget]! @stitch(
  key: "scope { group name }",
  arguments: "keys: {group: $scope.group, name: $scope.name}, other: 'Sfoo'"
)

The arguments param is parsed as a GraphQL inner-arguments literal. Then, paths from the key are inserted into the literal as a namespaced path prefixed by "$", ie: $scope.group. Some scoping rules would apply, as a repeatable key field can only be inserted into into a repeatable argument scope.

Arguments

type Widget {
  scope: String!
  name: String!
}

type Query {
  widget1(scope: String!, name: String!): Widget @stitch(
    key: "scope name",
    arguments: "scope: $scope, name: $name"
  )
  widget2(s: String!, n: String!): Widget @stitch(
    key: "scope name",
    arguments: "s: $scope, n: $name"
  )
}

Input objects

type Widget {
  scope: String!
  name: String!
}

input WidgetKey {
  scope: String!
  name: String!
}
input WidgetKey2 {
  s: String!
  n: String!
}
type Query {
  widgets(keys: [WidgetKey!]!): [Widget]! @stitch(
    key: "scope name", 
    arguments: "keys: {scope: $scope, name: $name}"
  )

  widget1(key: WidgetKey!): Widget @stitch(
    key: "scope name", 
    arguments: "key: {scope: $scope, name: $name}"
  )
  widget2(key: WidgetKey2!): Widget @stitch(
    key: "scope name", 
    arguments: "key: {s: $scope, n: $name}"
  )
  
  widget1(key: WidgetKey, other: String): Widget @stitch(
    key: "scope name", 
    arguments: "key: {scope: $scope, name: $name}, other: 'Sfoo'"
  )
  widget2(key: WidgetKey2, other: String): Widget @stitch(
    key: "scope name", 
    arguments: "key: {s: $scope, n: $name}, other: 'Sfoo'"
  )
}

Nested selections

type WidgetScope {
  group: String!
  name: String!
}
type Widget {
  scope: WidgetScope
  title: String
}

input WidgetKey {
  group: String!
  key: String!
}
type Query {
  widgets(keys: [WidgetKey!]!, other: String): [Widget]! @stitch(
    key: "scope { group name }",
    arguments: "keys: {group: $scope.group, name: $scope.name}, other: 'Sfoo'"
  )
}

Entity representations (Apollo Federation protocol)

type WidgetScope {
  group: String!
  name: String!
}
type Widget {
  scope: WidgetScope
  title: String
}

union _Entity = Widget
scalar _Any
type Query {
  # sends keys as JSON blobs:
  # [{"group": "a", name: "b", "__typename": "Widget"}, ...]
  _entities(representations: [_Any!]!): [_Entity]! @stitch(
    key: "scope { group name } __typename", 
    arguments: "representations: { group: $scope.group, name: $scope.name, __typename: $__typename }",
  )
}

Simple parser:

class ArgumentsParser
  class << self
    # "reps: {group: $scope.group, name: $scope.name}, other: 'Sfoo'""
    def parse(template)
      template = template.gsub("'", '"').gsub(/(\$[\w\.]+)/) { %|"#{_1}"| }
      GraphQL.parse("{ f(#{template}) }")
        .definitions.first
        .selections.first
        .arguments
    end
  end
end
@gmac gmac added the feature label Jun 3, 2024
@gmac gmac mentioned this issue Jun 30, 2024
@gmac gmac closed this as completed in #141 Jul 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant