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

Auto-generate GraphQL comments in SDL to support a self-documenting API #5824

Merged
merged 56 commits into from
Aug 4, 2022

Conversation

dthyresson
Copy link
Contributor

@dthyresson dthyresson commented Jun 25, 2022

I've wanted to support comments in SDL to help auto-generate a self-documenting GraphQL api for awhile.

It helps document in both the GraphiQL Playground, but also can be used by Docusaurus plug-ins to generate publishable docs. See: https://github.com/graphql-markdown/graphql-markdown

This PR adds comments to

  • SDL generators
  • root schema

with default comments and descriptions to help self-document the GraphQL API.

What are comments and descriptions?

See: graphql/graphql-spec#420

This can add comments in GraphiQL for:

  • redwood root schema and queries
  • queries
  • mutations
  • type/objects
  • input types for create and update
  • enums

For example:

image

image

image

image

image

Prisma Comments

Per @orta 's suggestion, the description now defaults to the Prisma documentation comment if present.

For example:

model WorldCity {
  /// The underlaying ID
  id           String   @id @default(uuid())
  /// Created at timestamp
  createdAt    DateTime @default(now())
  /// Created at timestamp
  updatedAt    DateTime @updatedAt
  /// The id in the SimpleMaps service
  simpleMapsId BigInt   @unique
  /// The name of a city
  city         String
  /// The name of a city in ASCII
  cityAscii    String
  /// Geocordinates of a city, latitude
  lat          Float
  /// Geocordinates of a city, longitude
  lng          Float
  /// Country in which the city is located
  country      String
...

Can default to ...

"""Representation of WorldCity."""
type WorldCity {
  """
  WeatherReport
  
  Description for WeatherReport.
  """
  WeatherReport: [WeatherReport]!

  """
  adminName
  
  Description for adminName.
  """
  adminName: String

  """
  capital
  
  Description for capital.
  """
  capital: String

  """
  city
  
  The name of a city
  """
  city: String!

  """
  cityAscii
  
  The name of a city in ASCII
  """
  cityAscii: String!

  """
  country
  
  Country in which the city is located
  """
  country: String!

  """
  createdAt
  
  Created at timestamp
  """
  createdAt: DateTime!

  """
  id
  
  The underlaying ID
  """
  id: String!

  """
  iso2
  
  Description for iso2.
  """
  iso2: String!

  """
  iso3
  
  Description for iso3.
  """
  iso3: String!

  """
  lat
  
  Geocordinates of a city, latitude
  """
  lat: Float!

  """
  lng
  
  Geocordinates of a city, longitude
  """
  lng: Float!

  """
  population
  
  Description for population.
  """
  population: Int

  """
  simpleMapsId
  
  The id in the SimpleMaps service
  """
  simpleMapsId: BigInt!

  """
  updatedAt
  
  Updated at timestamp
  """
  updatedAt: DateTime!
}

ToDo

  • Support enum model name documentation
  • Document how to use comments on Prisma schema to self-document GraphQL API
  • Demo Docusaurus plugin and document setup with screenshots.

Note:

I did consider added a generator option to include or exclude comment generation, but thought including comments is a better practice.

But, if others think they should be on be default with an option to run off (or vice versa) I can see that, too.

@netlify
Copy link

netlify bot commented Jun 25, 2022

Deploy Preview for redwoodjs-docs ready!

Name Link
🔨 Latest commit 2cde232
🔍 Latest deploy log https://app.netlify.com/sites/redwoodjs-docs/deploys/62ec00648250b000087dc236
😎 Deploy Preview https://deploy-preview-5824--redwoodjs-docs.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify site settings.

@dthyresson dthyresson added the release:feature This PR introduces a new feature label Jun 25, 2022
@dthyresson dthyresson self-assigned this Jun 25, 2022
@dthyresson dthyresson requested a review from Tobbe June 25, 2022 14:37
@dthyresson dthyresson marked this pull request as ready for review June 25, 2022 14:37
@orta
Copy link
Contributor

orta commented Jun 25, 2022

Nice work, I fully describe my prisma models with /// which also propogates into JSDocs, you might to have the generators bring them from the prisma file also

model Game {
  /// The underlaying ID
  id String @id @unique

  /// The pretty url reference for the game
  slug String @unique

  createdAt DateTime @default(now())
  updatedAt DateTime @default(now()) @updatedAt

  /// The pretty name for the game
  displayName String

  /// What the current SHA for the JS/files looks like
  assetsSha String

  /// Name of the function we should run
  exposedGlobalFunction String @default("runGameWithHost")

  ...

@dthyresson
Copy link
Contributor Author

dthyresson commented Jun 25, 2022

Nice work,

Thanks! @orta

I fully describe my prisma models with /// which also propogates into JSDocs,

Interesting.

Turns out Prisma does parse the schema in what it calls the DMMF document and each field has a name, type and .... documentation.

For example:

model WorldCity {
  /// The underlaying ID
  id           String   @id @default(uuid())
  /// Created at timestamp
  createdAt    DateTime @default(now())
  /// Created at timestamp
  updatedAt    DateTime @updatedAt
  /// The id in the SimpleMaps service
  simpleMapsId BigInt   @unique
  /// The name of a city
  city         String
  /// The name of a city in ASCII
  cityAscii    String
  /// Geocordinates of a city, latitude
  lat          Float
  /// Geocordinates of a city, longitude
  lng          Float
  /// Country in which the city is located
  country      String
...

Which I can then use to generate:

"""Representation of WorldCity."""
type WorldCity {
  """
  WeatherReport
  
  Description for WeatherReport.
  """
  WeatherReport: [WeatherReport]!

  """
  adminName
  
  Description for adminName.
  """
  adminName: String

  """
  capital
  
  Description for capital.
  """
  capital: String

  """
  city
  
  The name of a city
  """
  city: String!

  """
  cityAscii
  
  The name of a city in ASCII
  """
  cityAscii: String!

  """
  country
  
  Country in which the city is located
  """
  country: String!

  """
  createdAt
  
  Created at timestamp
  """
  createdAt: DateTime!

  """
  id
  
  The underlaying ID
  """
  id: String!

  """
  iso2
  
  Description for iso2.
  """
  iso2: String!

  """
  iso3
  
  Description for iso3.
  """
  iso3: String!

  """
  lat
  
  Geocordinates of a city, latitude
  """
  lat: Float!

  """
  lng
  
  Geocordinates of a city, longitude
  """
  lng: Float!

  """
  population
  
  Description for population.
  """
  population: Int

  """
  simpleMapsId
  
  The id in the SimpleMaps service
  """
  simpleMapsId: BigInt!

  """
  updatedAt
  
  Updated at timestamp
  """
  updatedAt: DateTime!
}

So, if there is a comment doc in Prisma, I use that or default.

Great idea!

@dthyresson dthyresson marked this pull request as draft June 25, 2022 19:46
@dthyresson dthyresson marked this pull request as ready for review June 25, 2022 22:41
@dthyresson
Copy link
Contributor Author

Have added docs option to optionally generate the SDL comments via sdl and scaffold generators. Defaults to false so no docs generated. Except for Redwood root schema and built in auth Directives which have comments.

Copy link
Member

@Tobbe Tobbe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Mostly want to default to single-line comments whenever possible to make it less verbose/overwhelming

docs/docs/cli-commands.md Outdated Show resolved Hide resolved
docs/docs/cli-commands.md Show resolved Hide resolved
docs/docs/graphql.md Outdated Show resolved Hide resolved
docs/docs/graphql.md Outdated Show resolved Hide resolved
docs/docs/graphql.md Outdated Show resolved Hide resolved
packages/cli/src/commands/generate/sdl/sdl.js Outdated Show resolved Hide resolved
Co-authored-by: Tobbe Lundberg <[email protected]>
@dthyresson
Copy link
Contributor Author

The GraphQL spec says that the contents of the block string can be markdown, so I'm not sure why it's throwing. 🤔 Can you reproduce?

I don't think you can use any markdown.

To allow GraphQL service designers to easily publish documentation alongside the capabilities of a GraphQL service, GraphQL descriptions are defined using the Markdown syntax (as specified by CommonMark). In the type system definition language, these description strings (often BlockString) occur immediately before the definition they describe.

It just says that you can use the "block string" which is mark of markdown.

I tried and got errors. But I think that is expected.

Another suggestion (maybe similar to what @Tobbe was suggesting): maybe we should make field comments use only one set of quotes instead of three? To match the example in the GraphQL spec: http://spec.graphql.org/draft/#example-916f4. Prettier seems to be forcing triple-quote descriptions onto their own line, but it leaves single-quote descriptions alone. That would keep the file from getting too big too fast. Thoughts?

Done!

@dthyresson
Copy link
Contributor Author

I haven't gotten to the docs yet, just focused on the code

@jtoar I've updated the docs to match the quotation use. Should be good to go.

@jtoar jtoar self-assigned this Aug 2, 2022
docs/docs/graphql.md Outdated Show resolved Hide resolved
docs/docs/graphql.md Outdated Show resolved Hide resolved
docs/docs/graphql.md Outdated Show resolved Hide resolved
docs/docs/graphql.md Outdated Show resolved Hide resolved
docs/docs/graphql.md Outdated Show resolved Hide resolved
docs/docs/graphql.md Outdated Show resolved Hide resolved
docs/docs/graphql.md Outdated Show resolved Hide resolved
docs/docs/graphql.md Outdated Show resolved Hide resolved
docs/docs/graphql.md Outdated Show resolved Hide resolved
docs/docs/graphql.md Outdated Show resolved Hide resolved
@dthyresson dthyresson enabled auto-merge (squash) August 4, 2022 17:31
@dthyresson dthyresson merged commit f699e31 into redwoodjs:main Aug 4, 2022
@redwoodjs-bot redwoodjs-bot bot added this to the next-release milestone Aug 4, 2022
@jtoar jtoar modified the milestones: next-release, v3.0.0 Sep 2, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release:feature This PR introduces a new feature
Projects
Status: Done
Development

Successfully merging this pull request may close these issues.

4 participants