Why I think GraphQL is pretty neat, the implementation
Tags: typescript, graphql
Published: 2020-07-10 12:00:35

In my last post, I wrote about why I think GraphQL as a concept is pretty neat. This time I will try, through implementation, to show that it is indeed pretty neat.

In my last blog post which you can [find here](https://dev.to/itminds/why-i-think-graphql-is-pretty-neat-14i6), I teased about what stack I would be using, but just to reclarify, this is it:

- **Language**: Typescript
- **Server**: NexusJS
- **Frontend-UI**: React
- **Frontend-Network**: Apollo-client

## Let's go!

I like to write less to do more. I know some might find this as magic, and I tend to agree. Sometimes. When it comes to decreasing the time to market with a product, I think it's good with a little magic. 

Using [NexusJS](https://nexusjs.org/) can very easily feel like magic. First of all, the actual file that starts the server can be as bare as this:


```typescript
import { schema } from 'nexus'

schema.objectType({
  name: 'SupremeLeader',
  definition(t) {
    t.id('id')            
  },
})
```

Notice, how there I nowhere specify my server or what port to listen on.

Nexus will abstract this away and just let me run `nexus dev` in my terminal, and I will be hitting the ground running!

Now I know that some will say that this is the worst idea ever, but I would have to respectfully disagree. And just to point out, you can, though ENV variables choose which port nexus will use under the hood, and you can also hook into the underlying express server to add your own configuration middleware, should you be so inclined. 


My experience with nexus has been: provides sensible defaults, but open for configuration.

Which I happen to think is a good standpoint to take no matter what type of library/framework you are creating.


Anyways, back to the code:

What the above code does for me is to create a single type on my schema. However, at this point, there is no way we can get any data from the server. Therefor, let's implement a query so that we can get some glorious posts from our graph!

```ts
schema.extendType({
  type: "Query",
  definition(t) {
    t.field("gloriusLeader", {
      type: "SupremeLeader",
      resolve(parent, args, context) {
          return {
              id: 0
          };
        }
      });
    }
});
```

Above we create a query to get ourselves a SupremeLeader through the `gloriousLeader` handle.

How about we see how this query works then?

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/xghj6qnunpe1lvl7kkv2.png)

This query is pretty useless since it's only returning 1, and only an `id` field, but from here you can grow the schema to whatever size you want. Pretty neat.


Let's see how we use this API to create our SupremeLeader a glorious frontend as well!


```typescript
schema.extendType({
    type: "Mutation",
    definition(t) {
        t.field("birthNewSupremeLeader", {
            type: "String",
            resolve(parent, args, context) {
                return `All hail our new king`;
            }
        });
    }
});
```

When manipulating data we call `mutations` - in essence this is just a name, and not a constraint.

That means that queries essentially can manipulate data. But to make sure that we as developers know if our interactions have side effects on the data, the GraphQL spec splits them up into these two. 

The above mutation does nothing but return string indicating success, but whatever logic you would want can be put here.

Just for the fun, let's see how much code we need then to create a GraphQL service that has a `SupremeLeader` model a query to fetch it, and a mutation to add one.

![file system](https://dev-to-uploads.s3.amazonaws.com/i/15kxnyrdf6gvz57p764p.png)

Okay, some pretty basic files here. The only part that really does something here is the app.ts. That's the file I have been showing snippets of.

So to make a small service that exposes a GraphQL API, with albeit slim to 0 functionality, you really only need 3 files, a `app.ts` containing the GraphQL code, a `package.json` file defining the project and its dependencies, and a `tsconfig.json` file with the typescript setup you need to 'typescript' away.

What you get, however, is an API, documentation (in the form of the types the schema provides), a playground to test your API in, and so much developer happiness that you could just burst.

I hope you liked this post and if you have any questions please let me know in the comments.