lit-gql

graphql in javascript

Usage no npm install needed!

<script type="module">
  import litGql from 'https://cdn.skypack.dev/lit-gql';
</script>

README

@literally/gql

One of the drawbacks of schema-first development is that graphql resolvers are defined separately from their type definitions. Unlike code-first development where type definitions and resolvers can be inlined.

But, the drawback of code-first development is that it's too verbose, and builds yet another layer of abstraction upon a language.

Can we use Javascript to enhance schema-fist development? All a schema is, is a string; and we already have ways of embedding expressions inside strings: ${expression}. Using embedded string expressions to enhance a language with Javascript while preserving it's natural syntax was popularized in front-end programming with css-in-js libraries like styled-components. And it's an approach that also naturally fits for schema-first development.

We can embrace the schema-first string literal syntax, and inject resolvers as embedded expressions wrapped inside custom directives.

Here's an example:

gql`
  type Query {
    user(id: ID!): User! @resolve(${(_, { id }, { db }) => db.User.findMany({ id })})
    notes(userId: ID!): [Notes]! @resolve(${(_, { userId }, { db }) => db.Note.findOne({ userId })})
  }

  type Mutation {
    createNote(data: CreateNoteData!): Note! @resolve(${_, { data }, { db } => db.Note.create(data)}) 
  }

  type User {
    id: ID!
    username: String!
    firstName: String! 
    lastName: String! 
    fullName: String! @resolve(${user => user.username})
    notes: Notes! @resolve(${(user, _, { db }) => db.Note.findMany({ userId: user.id })})
  }

  type Notes {
    id: ID! 
    doc: NoteDocument!
  }

  type CreateNoteData {
    doc: NoteDocument!
  }

  scalar NoteDocument @resolve(${NoteDocumentScalar})
`