ローカルでGraphQL サーバー構築(その1. Apolloを利用したgraphqlサーバー立ち上げまで)

# やること: 
- [ ] graphqlのスキーマの定義
- [ ] データセットの用意
- [ ] graphqlのリゾルバの定義
- [ ] apolloサーバー立ち上げ
- [ ] playgroundでテスト


## graphqlのスキーマの定義
参考: [APOLLO DOCS](https://www.apollographql.com/docs/apollo-server/getting-started)

**Step 1: Create a new project**
```sh:bash
$ mkdir graphql-server-example
$ cd graphql-server-example
```

```sh:bash
$ npm init --yes
Wrote to /home/yuki-kitazawa/practice/graphql-server-example/package.json:

{
  "name": "graphql-server-example",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [],
  "author": "",
  "license": "ISC"
}
```

**Step 2: Install dependencies**

```sh:bash
$ npm install @apollo/server graphql

added 122 packages, and audited 123 packages in 12s

8 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
```

* typescriptのセットアップ
```:bash
$ mkdir src
$ touch src/index.ts
```

```sh:bash
npm install --save-dev typescript @types/node
```

```sh:bash
$ vim tsconfig.json
$ cat tsconfig.json 
{
  "compilerOptions": {
    "rootDirs": ["src"],
    "outDir": "dist",
    "lib": ["es2020"],
    "target": "es2020",
    "module": "esnext",
    "moduleResolution": "node",
    "esModuleInterop": true,
    "types": ["node"]
  }
```

```sh:bash
$ cp package.json package.json.bk
$ vim package.json
$ diff -u package.json.bk package.json
--- package.json.bk     2022-12-30 21:59:05.317594058 +0900
+++ package.json        2022-12-30 22:01:04.598150054 +0900
@@ -3,7 +3,10 @@
   "version": "1.0.0",
   "description": "",
   "main": "index.js",
+  "type": "module",
   "scripts": {
+    "compile": "tsc",
+    "start": "npm run compile && node ./dist/index.js",
     "test": "echo \"Error: no test specified\" && exit 1"
   },
   "keywords": [],
$ rm package.json.bk 
```

**Step 3: Define your GraphQL schema**

```ts:index.ts
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';

const typeDefs = `#graphql

  type Book {
    title: String
    author: String
  }

  type Query {
    books: [Book]
  }
`;
```

## データセットの用意
**Step 4: Define your data set**

```ts:index.ts
const books = [
    {
      title: 'The Awakening',
      author: 'Kate Chopin',
    },
    {
      title: 'City of Glass',
      author: 'Paul Auster',
    },
  ];

```

## graphqlのリゾルバの定義
**Step 5: Define a resolver**
```ts:index.ts
const resolvers = {
    Query: {
      books: () => books,
    },
};
```

## apolloサーバー立ち上げ
**Step 6: Create an instance of ApolloServer**
```ts:index.ts
const server = new ApolloServer({
  typeDefs,
  resolvers,
});

const { url } = await startStandaloneServer(server, {
  listen: { port: 4000 },
});

console.log(`🚀  Server ready at: ${url}`);
```

**Step 7: Start the server**
```sh:bash
$ npm start

> graphql-server-example@1.0.0 start
> npm run compile && node ./dist/index.js


> graphql-server-example@1.0.0 compile
> tsc

🚀  Server ready at: http://localhost:4000/
```


## playgroundでテスト
**Step 8: Execute your first query**
* http://localhost:4000 を開く
* クエリをテストできる。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2193053/690b2d72-8bac-e826-8f8b-f0750fd04810.png)