awslabs / aws-mobile-appsync-sdk-js

JavaScript library files for Offline, Sync, Sigv4. includes support for React Native
Apache License 2.0
921 stars 266 forks source link

'Partial Schema' for all AWS AppSync specific directives/types/etc #547

Closed 0xdevalias closed 4 years ago

0xdevalias commented 4 years ago

Do you want to request a feature or report a bug?

feature

What is the current behavior?

Currently the seemed only way to get the full AWS AppSync schema (including AWS specific directives/etc) is to export the .json schema from the AppSync console.

What is the expected behavior?

I would much rather have a canonical 'AWS Specifics' partial schema that I can reference, and then just use the .graphql for my specific custom schema (as it is WAY less verbose)

This leads to issues with parsers/linters/etc that don't understand the AWS AppSync specific directives.

eg. https://github.com/apollographql/eslint-plugin-graphql/issues/263

Which versions and which environment (browser, react-native, nodejs) / OS are affected by this issue? Did this work in previous versions?

All, no.

0xdevalias commented 4 years ago

I can see the following when playing around with jq:

⇒  jq '.data.__schema.directives[] | .name' schema.json
"include"
"skip"
"defer"
"aws_oidc"
"aws_auth"
"aws_publish"
"aws_cognito_user_pools"
"deprecated"
"aws_subscribe"
"aws_iam"
"aws_api_key"
⇒  jq '.data.__schema.directives[0] | keys' schema.json
[
  "args",
  "description",
  "locations",
  "name",
  "onField",
  "onFragment",
  "onOperation"
]
⇒  jq '.data.__schema.directives[6]' schema.json
{
  "name": "aws_cognito_user_pools",
  "description": "Tells the service this field/object has access authorized by a Cognito User Pools token.",
  "locations": [
    "OBJECT",
    "FIELD_DEFINITION"
  ],
  "args": [
    {
      "name": "cognito_groups",
      "description": "List of cognito user pool groups which have access on this field",
      "type": {
        "kind": "LIST",
        "name": null,
        "ofType": {
          "kind": "SCALAR",
          "name": "String",
          "ofType": null
        }
      },
      "defaultValue": null
    }
  ],
  "onOperation": false,
  "onFragment": false,
  "onField": false
}
0xdevalias commented 4 years ago

Using https://github.com/potatosalad/graphql-introspection-json-to-sdl we can convert the .json to .graphql

npx graphql-introspection-json-to-sdl schema.json > schema-converted.graphql

This seems to produce a MUCH simpler representation, which (assuming it worked properly?) may actually be the minimal set of AWS AppSync customisations..

"""This directive allows results to be deferred during execution"""
directive @defer on FIELD

"""
Tells the service this field/object has access authorized by an OIDC token.
"""
directive @aws_oidc on OBJECT | FIELD_DEFINITION

"""Directs the schema to enforce authorization on a field"""
directive @aws_auth(
  """List of cognito user pool groups which have access on this field"""
  cognito_groups: [String]
) on FIELD_DEFINITION

"""
Tells the service which subscriptions will be published to when this mutation is
called. This directive is deprecated use @aws_susbscribe directive instead.
"""
directive @aws_publish(
  """
  List of subscriptions which will be published to when this mutation is called.
  """
  subscriptions: [String]
) on FIELD_DEFINITION

"""
Tells the service this field/object has access authorized by a Cognito User Pools token.
"""
directive @aws_cognito_user_pools(
  """List of cognito user pool groups which have access on this field"""
  cognito_groups: [String]
) on OBJECT | FIELD_DEFINITION

"""Tells the service which mutation triggers this subscription."""
directive @aws_subscribe(
  """
  List of mutations which will trigger this subscription when they are called.
  """
  mutations: [String]
) on FIELD_DEFINITION

"""
Tells the service this field/object has access authorized by sigv4 signing.
"""
directive @aws_iam on OBJECT | FIELD_DEFINITION

"""
Tells the service this field/object has access authorized by an API key.
"""
directive @aws_api_key on OBJECT | FIELD_DEFINITION
0xdevalias commented 4 years ago

It seems there may be more than just the directives:

0xdevalias commented 4 years ago

Exporting another of my 'real' AppSync configs then converting gives me a few of the scalars:

"""
The `AWSDateTime` scalar type provided by AWS AppSync, represents a valid
***extended*** [ISO 8601 DateTime](https://en.wikipedia.org/wiki/ISO_8601#Combined_date_and_time_representations)
string. In other words, this scalar type accepts datetime strings of the form
`YYYY-MM-DDThh:mm:ss.SSSZ`.  The scalar can also accept "negative years" of the
form `-YYYY` which correspond to years before `0000`. For example,
"**-2017-01-01T00:00Z**" and "**-9999-01-01T00:00Z**" are both valid datetime
strings.  The field after the two digit seconds field is a nanoseconds field. It
can accept between 1 and 9 digits. So, for example,
"**1970-01-01T12:00:00.2Z**", "**1970-01-01T12:00:00.277Z**" and
"**1970-01-01T12:00:00.123456789Z**" are all valid datetime strings.  The
seconds and nanoseconds fields are optional (the seconds field must be specified
if the nanoseconds field is to be used).  The [time zone
offset](https://en.wikipedia.org/wiki/ISO_8601#Time_zone_designators) is
compulsory for this scalar. The time zone offset must either be `Z`
(representing the UTC time zone) or be in the format `±hh:mm:ss`. The seconds
field in the timezone offset will be considered valid even though it is not part
of the ISO 8601 standard.
"""
scalar AWSDateTime

"""
The `AWSJSON` scalar type provided by AWS AppSync, represents a JSON string that
complies with [RFC 8259](https://tools.ietf.org/html/rfc8259).  Maps like
"**{\\"upvotes\\": 10}**", lists like "**[1,2,3]**", and scalar values like
"**\\"AWSJSON example string\\"**", "**1**", and "**true**" are accepted as
valid JSON and will automatically be parsed and loaded in the resolver mapping
templates as Maps, Lists, or Scalar values rather than as the literal input
strings.  Invalid JSON strings like "**{a: 1}**", "**{'a': 1}**" and "**Unquoted
string**" will throw GraphQL validation errors.
"""
scalar AWSJSON

It seems maybe they won't be included unless we've actually used them in our schema, so might have to contrive a schema that uses all of the AWS AppSync specific customisations, then export the .json, and then re-convert it.

elorzafe commented 4 years ago

@0xdevalias thanks for your feedback, this seems to be a feature request for AppSync service rather than the AppSync SDK. I will forward this to someone from that team but for service related issues please it will be handled better on the official AWS AppSync forum

elorzafe commented 4 years ago

I will close this issue but please feel free to open issue related to AppSync SDK here

0xdevalias commented 4 years ago

While yes it may bet better ‘ultimately’ solved by AppSync itself, given the types aren’t going to change often it’s the kind of thing that could easily be figured out once and included in a library such as this to make devs lives easier.

My experience with AWS services is that the ‘core service teams/features’ tend to move WAY slower than the ‘supporting libraries teams’, and thus it tends to be better raising things in places like this.

elorzafe commented 4 years ago

@0xdevalias there is also the AppSync Community on github where you can also create an issue for this.

0xdevalias commented 4 years ago

@elorzafe Oh interesting! Didn’t even realise that existed! Thanks :)