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

Add alternatives to docs #108

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions website/docs/03-resolvers/_category_.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"collapsible": false,
"collapsed": false
"collapsible": true,
"collapsed": true
}
4 changes: 2 additions & 2 deletions website/docs/04-docblock-tags/_category_.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"collapsed": false,
"collapsible": false
"collapsed": true,
"collapsible": true
}
4 changes: 2 additions & 2 deletions website/docs/05-guides/_category_.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"label": "Guides",
"collapsed": false,
"collapsible": false,
"collapsed": true,
"collapsible": true,
"link": {}
}
39 changes: 39 additions & 0 deletions website/docs/06-alternatives/01-pothos.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import GratsCode from "@site/src/components/GratsCode";
import Example from "!!raw-loader!./snippets/pothos.out";

# Pothos

From https://pothos-graphql.dev/

```typescript
import { createYoga } from "graphql-yoga";
import { createServer } from "node:http";
import SchemaBuilder from "@pothos/core";

const builder = new SchemaBuilder({});

builder.queryType({
fields: (t) => ({
hello: t.string({
args: {
name: t.arg.string(),
},
resolve: (parent, { name }) => `hello, ${name || "World"}`,
}),
}),
});

const yoga = createYoga({
schema: builder.toSchema(),
});

const server = createServer(yoga);

server.listen(3000, () => {
console.log("Visit http://localhost:3000/graphql");
});
```

## Grats

<GratsCode out={Example} mode="ts" />
36 changes: 36 additions & 0 deletions website/docs/06-alternatives/02-typegraphql.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import GratsCode from "@site/src/components/GratsCode";
import Example from "!!raw-loader!./snippets/typegraphql.out";

# TypeGraphQL

From https://typegraphql.com/

```typescript
@ObjectType()
export class Rate {
@Field((type) => Int)
value: number;
}

@ObjectType()
class Recipe {
@Field()
title: string;

@Field({ nullable: true })
description?: string;

@Field((type) => [Float])
ratings: number[];

@Field((type) => Float, { nullable: true })
get averageRating() {
const sum = this.ratings.reduce((a, b) => a + b, 0);
return sum / this.ratings.length;
}
}
```

## Grats

<GratsCode out={Example} mode="ts" />
23 changes: 23 additions & 0 deletions website/docs/06-alternatives/03-nexus.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import GratsCode from "@site/src/components/GratsCode";
import Example from "!!raw-loader!./snippets/nexus.out";

# Nexus

From https://nexusjs.org/docs/getting-started/tutorial/chapter-writing-your-first-schema

```typescript
import { objectType } from "nexus";
export const Post = objectType({
name: "Post", // <- Name of your type
definition(t) {
t.int("id"); // <- Field named `id` of type `Int`
t.string("title"); // <- Field named `title` of type `String`
t.string("body"); // <- Field named `body` of type `String`
t.boolean("published"); // <- Field named `published` of type `Boolean`
},
});
```

## Grats

<GratsCode out={Example} mode="ts" />
61 changes: 61 additions & 0 deletions website/docs/06-alternatives/04-graphql-js.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import GratsCode from "@site/src/components/GratsCode";
import Example from "!!raw-loader!./snippets/graphql-js.out";

# GraphQL.js

From https://graphql.org/graphql-js/constructing-types/

```typescript
var express = require("express");
var { graphqlHTTP } = require("express-graphql");
var graphql = require("graphql");

// Maps id to User object
var fakeDatabase = {
a: { id: "a", name: "alice" },
b: { id: "b", name: "bob" },
};

// Define the User type
var userType = new graphql.GraphQLObjectType({
name: "User",
fields: {
id: { type: graphql.GraphQLString },
name: { type: graphql.GraphQLString },
},
});

// Define the Query type
var queryType = new graphql.GraphQLObjectType({
name: "Query",
fields: {
user: {
type: userType,
// `args` describes the arguments that the `user` query accepts
args: {
id: { type: graphql.GraphQLString },
},
resolve: (_, { id }) => {
return fakeDatabase[id];
},
},
},
});

var schema = new graphql.GraphQLSchema({ query: queryType });

var app = express();
app.use(
"/graphql",
graphqlHTTP({
schema: schema,
graphiql: true,
}),
);
app.listen(4000);
console.log("Running a GraphQL API server at localhost:4000/graphql");
```

## Grats

<GratsCode out={Example} mode="ts" />
81 changes: 81 additions & 0 deletions website/docs/06-alternatives/05-gqtx.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import GratsCode from "@site/src/components/GratsCode";
import Example from "!!raw-loader!./snippets/gqtx.out";

# Gqtx

From https://github.com/sikanhe/gqtx

```typescript
import { Gql, buildGraphQLSchema } from "gqtx";

enum Role {
Admin,
User,
}

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

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

// We can declare the app context type once, and it will
// be automatically inferred for all our resolvers
declare module "gqtx" {
interface GqlContext {
viewerId: number;
users: User[];
}
}

const RoleEnum = Gql.Enum({
name: "Role",
description: "A user role",
values: [
{ name: "Admin", value: Role.Admin },
{ name: "User", value: Role.User },
],
});

const UserType = Gql.Object<User>({
name: "User",
description: "A User",
fields: () => [
Gql.Field({ name: "id", type: Gql.NonNull(Gql.ID) }),
Gql.Field({ name: "role", type: Gql.NonNull(RoleEnum) }),
Gql.Field({ name: "name", type: Gql.NonNull(Gql.String) }),
],
});

const Query = Gql.Query({
fields: [
Gql.Field({
name: "userById",
type: UserType,
args: {
id: Gql.Arg({ type: Gql.NonNullInput(Gql.ID) }),
},
resolve: (_, args, ctx) => {
// `args` is automatically inferred as { id: string }
// `ctx` (context) is also automatically inferred as { viewerId: number, users: User[] }
const user = ctx.users.find((u) => u.id === args.id);
// Also ensures we return an `User | null | undefined` type
return user;
},
}),
],
});

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

## Grats

<GratsCode out={Example} mode="ts" />
4 changes: 4 additions & 0 deletions website/docs/06-alternatives/_category_.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"collapsed": true,
"collapsible": true
}
11 changes: 11 additions & 0 deletions website/docs/06-alternatives/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Alternatives

In this section, we have taken "hello world" examples from the documentation of various other competing tools and reimplemented them with Grats. The hope is that this will give you a quick sense of how it would feel to use Grats as compared to other tools.

## Comparisons

- [Pothos](./01-pothos.mdx)
- [TypeGraphQL](./02-typegraphql.mdx)
- [Nexus](./03-nexus.mdx)
- [GraphQL.js](./04-graphql-js.mdx)
- [Gqtx](./05-gqtx.mdx)
45 changes: 45 additions & 0 deletions website/docs/06-alternatives/snippets/gqtx.grats.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { ID } from "grats";
import { getSchema } from "./schema"; // Generated by Grats

/**
* A user role
* @gqlEnum
*/
enum Role {
Admin = "Admin",
User = "User",
}

/** @gqlType */
type User = {
/** @gqlField */
id: ID;
/** @gqlField */
role: Role;
/** @gqlField */
name: string;
};

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

interface GqlContext {
viewerId: number;
users: User[];
}

/** @gqlType */
type Query = unknown;

/** @gqlField */
export function userById(
_: Query,
args: { id: string },
ctx: GqlContext,
): User | null {
return users.find((u) => u.id === args.id) || null;
}

const schema = getSchema();
Loading