0.9.3 • Published 4 months ago

gqtx v0.9.3

Weekly downloads
1,276
License
MIT
Repository
github
Last release
4 months ago

Why another GraphqQL Server?

Getting Started

Type-safety without manual work

gqtx is a thin layer on top of graphql-js for writing a type-safe GraphQL server in TypeScript. It provides you with a set of helper functions to create an intermediate representation of a GraphQL schema, and then converts that schema to a raw graphql-js schema. So you get to use everything from the reference implementation of GraphQL, but with way more type safety.

If a schema compiles, the following holds:

  • The type of a field agrees with the return type of the resolver.
  • The arguments of a field agrees with the accepted arguments of the resolver.
  • The source of a field agrees with the type of the object to which it belongs.
  • The return type of the resolver will not be input types (InputObject)
  • The arguments of a field will not be abstract types (Interface, Union)
  • The context argument for all resolver functions in a schema agree.

Most importantly, we achieve all this without having to:

  • Set up code generation tools
  • Write SDL and having your schema partially defined in code and in a DSL file
  • Require special compiler magic such as reflect-metadata and decorators

What does it look like?

import { createTypesFactory, buildGraphQLSchema } from 'gqtx';

enum Role {
  Admin,
  User,
}

type User = {
  id: number;
  role: Role;
  name: string;
};

const users: User[] = [
  { id: 1, role: Role.Admin, name: 'Sikan' },
  { id: 2, role: Role.User, name: 'Nicole' },
];

type AppContext = {
  viewerId: 1,
  users: User[]
}

// We can set the app context type once, and it will
// be automatically inferred for all our resolvers! :)
const t = createTypesFactory<AppContext>();

const RoleEnum = t.enumType({
  name: 'Role',
  description: 'A user role',
  values: [{ name: 'Admin', value: Role.Admin }, { name: 'User', value: Role.User }],
});

const UserType = t.objectType<User>({
  name: 'User',
  description: 'A User',
  fields: () => [
    t.defaultField('id', t.NonNull(t.ID)),
    t.defaultField('role', t.NonNull(RoleEnum)),
    // `defaultField` is the safe version of a default resolver
    // field. In this case, field 'name' must exist on `User`
    // and its type must be `string`
    t.defaultField('name', t.NonNull(t.String)),
  ],
});

const Query = t.queryType({
  fields: [
    t.field('userById', {
      type: UserType,
      args: {
        id: t.arg(t.NonNullInput(t.ID)),
      },
      resolve: (_, args, ctx) => {
        // `args` is automatically inferred as { id: string }
        // `ctx` is also automatically inferred as AppContext
        //  All with no extra work!
        const user = ctx.users.find(u => u.id === args.id);
        // Also ensures we return an `User | null` type :)
        return user || null;
      },
    })
  ],
});

const schema = buildGraphQLSchema({
  query: Query,
});

Use your favorite server option to serve the schema!

import express from 'express';
import graphqlHTTP from 'express-graphql';

const app = express();

app.use(
  '/graphql',
  graphqlHTTP({
    schema,
    graphiql: true,
  })
);

app.listen(4000);

To Recap

  • We created an intermediate representation of a GraphQL schema via the helper functions exported by this library.
  • Then, we converted the schema to a real graphql-js schema by calling buildGraphQLSchema at server startup time.
  • Used existing express middleware express-graphql to server our schema with graphiql explorer
  • That's it! We get a fully typesafe server with almost zero type annotation needed
0.9.4-91f52af3.0

4 months ago

0.9.4-4e327db6.0

5 months ago

0.9.1-c4ab34ed.0

5 months ago

0.9.1-1a6de3de.0

5 months ago

0.9.1-6980048c.0

6 months ago

0.9.1-c6b228ee.0

5 months ago

0.9.1-b3f51155.0

5 months ago

0.9.2-528a0e50.0

5 months ago

0.9.1-b19576fb.0

6 months ago

0.9.1-92c61959.0

5 months ago

0.9.1-7cba2e90.0

5 months ago

0.9.1-13f4d9d4.0

6 months ago

0.9.1-f7ceec16.0

5 months ago

0.9.0

5 months ago

0.9.2

5 months ago

0.9.1

5 months ago

0.9.4-a59e0642.0

5 months ago

0.9.3

5 months ago

0.9.1-b5842d78.0

5 months ago

0.9.1-b5aa6892.0

5 months ago

0.9.1-4275e372.0

5 months ago

0.9.1-f7eeeff9.0

6 months ago

0.9.1-ea94d732.0

5 months ago

0.9.1-ad0529f1.0

5 months ago

0.9.4-cd9c5f90.0

5 months ago

0.9.1-8cac6ce9.0

5 months ago

0.9.2-e8f00210.0

5 months ago

0.9.1-4f98955f.0

9 months ago

0.9.1-28ee91ab.0

9 months ago

0.9.1-0bdd7c01.0

9 months ago

0.9.1-d25fc0bf.0

9 months ago

0.9.1-3138c3d4.0

9 months ago

0.9.1-fc0f1d45.0

9 months ago

0.9.1-7372732c.0

9 months ago

0.9.1-ab5408fa.0

9 months ago

0.9.1-a8f1266f.0

9 months ago

0.9.1-90435835.0

9 months ago

0.8.2-1c709b52.0

2 years ago

0.8.2-d93e811f.0

2 years ago

0.8.2-418ce4f0.0

2 years ago

0.8.2-b0af869e.0

2 years ago

0.8.2-4c93b62b.0

2 years ago

0.8.2-6e5f14ce.0

2 years ago

0.8.1-8b34dff2.0

3 years ago

0.8.1-d6e00cf5.0

3 years ago

0.8.2-3564db83.0

2 years ago

0.8.2-21daae90.0

3 years ago

0.8.1-4fb667a5.0

3 years ago

0.8.1

3 years ago

0.8.0

3 years ago

0.8.1-348cf7b3.0

3 years ago

0.8.1-cebe95c4.0

3 years ago

0.8.1-1c11cc95.0

3 years ago

0.8.1-f0517487.0

3 years ago

0.8.1-a41a109e.0

3 years ago

0.8.1-57a053d5.0

3 years ago

0.8.1-e5b86bfd.0

3 years ago

0.8.1-787c9945.0

3 years ago

0.8.1-e6f907e5.0

3 years ago

0.8.1-f565abfa.0

3 years ago

0.8.1-a2f3955c.0

3 years ago

0.8.1-63896ded.0

3 years ago

0.8.1-4382fc73.0

3 years ago

0.8.1-49644f7f.0

3 years ago

0.8.1-684296a9.0

3 years ago

0.8.1-fa8ead4a.0

3 years ago

0.8.1-0708dc94.0

3 years ago

0.8.1-f4332114.0

3 years ago

0.8.1-cc4454a0.0

3 years ago

0.8.1-d21f1065.0

3 years ago

0.8.1-d8783c21.0

3 years ago

0.8.1-f6e42aad.0

3 years ago

0.8.1-54deec7e.0

3 years ago

0.8.1-5ebc7631.0

3 years ago

0.8.1-f78dc66d.0

3 years ago

0.8.1-ac533978.0

3 years ago

0.8.1-1b4add73.0

3 years ago

0.8.1-dea3affd.0

3 years ago

0.8.1-913ef0b2.0

3 years ago

0.8.1-a395e824.0

3 years ago

0.8.1-bea53389.0

3 years ago

0.8.1-7cf0d3af.0

3 years ago

0.8.1-a9325d31.0

3 years ago

0.8.1-800c992a.0

3 years ago

0.8.0-beta.1

3 years ago

0.8.0-beta.0

3 years ago

0.7.0

4 years ago

0.6.0

4 years ago

0.5.0

5 years ago

0.4.1

5 years ago

0.4.0

5 years ago

0.3.0

5 years ago

0.2.1

5 years ago

0.2.0

5 years ago

0.1.0

5 years ago