Apollo Server の使い方

GraphQL サーバーの Apollo Server の使い方です。
ほぼ、こちらのページの通りです。
[Get started with Apollo Server](https://www.apollographql.com/docs/apollo-server/getting-started/)

## ファルダーの作成とライブラリーのインストール

```bash
mkdir graphql-server-example
cd graphql-server-example
npm init --yes
npm install apollo-server graphql
```

## サーバープログラム

```js:index.js
const { ApolloServer, gql } = require('apollo-server');

// A schema is a collection of type definitions (hence "typeDefs")
// that together define the "shape" of queries that are executed against
// your data.
const typeDefs = gql`
  # Comments in GraphQL strings (such as this one) start with the hash (#) symbol.

  # This "Book" type defines the queryable fields for every book in our data source.
  type Book {
    title: String
    author: String
  }

  # The "Query" type is special: it lists all of the available queries that
  # clients can execute, along with the return type for each. In this
  # case, the "books" query returns an array of zero or more Books (defined above).
  type Query {
    books: [Book]
  }
`;


const books = [
  {
    title: '心',
    author: '夏目漱石',
  },
  {
    title: '舞姫',
    author: '森鴎外',
  },
    {
    title: '春',
    author: '島崎藤村',
  },
];


// Resolvers define the technique for fetching the types defined in the
// schema. This resolver retrieves books from the "books" array above.
const resolvers = {
  Query: {
    books: () => books,
  },
};

// The ApolloServer constructor requires two parameters: your schema
// definition and your set of resolvers.
const server = new ApolloServer({ typeDefs, resolvers });

// The `listen` method launches a web server.
server.listen().then(({ url }) => {
  console.log(`🚀  Server ready at ${url}`);
});
```

## サーバーの起動

```text
$ node index.js
🚀  Server ready at http://localhost:4000/
```

## クライアントのプログラム

```bash:client.sh
curl -X POST \
	-H "Content-Type: application/json" \
	-d '{"query": "{ books {title,author} }"}' \
	http://localhost:4000/ | jq
```

実行結果

```text
$ ./client.sh 
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   178  100   141  100    37   4028   1057 --:--:-- --:--:-- --:--:--  5235
{
  "data": {
    "books": [
      {
        "title": "心",
        "author": "夏目漱石"
      },
      {
        "title": "舞姫",
        "author": "森鴎外"
      },
      {
        "title": "春",
        "author": "島崎藤村"
      }
    ]
  }
}
```

HTTPie で書いたクライアント

```bash:httpie.sh
http POST http://localhost:4000/ query="query { books { title author } }"
```

実行結果

```text
$ ./httpie.sh 
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Connection: keep-alive
Content-Length: 141
Content-Type: application/json; charset=utf-8
Date: Sun, 20 Feb 2022 06:59:42 GMT
ETag: W/"8d-EeJBaKYYZfqDVddcNwDtJvE6zuM"
Keep-Alive: timeout=5

{
    "data": {
        "books": [
            {
                "author": "夏目漱石",
                "title": "心"
            },
            {
                "author": "森鴎外",
                "title": "舞姫"
            },
            {
                "author": "島崎藤村",
                "title": "春"
            }
        ]
    }
}
```

## 確認したバージョン

```text
$ node --version
v19.8.1

$ curl --version
curl 8.0.1 (x86_64-pc-linux-gnu) libcurl/8.0.1 OpenSSL/3.0.8 zlib/1.2.13 brotli/1.0.9 zstd/1.5.4 libidn2/2.3.4 libpsl/0.21.2 (+libidn2/2.3.4) libssh2/1.10.0 nghttp2/1.52.0
Release-Date: [unreleased]
Protocols: dict file ftp ftps gopher gophers http https imap imaps mqtt pop3 pop3s rtsp scp sftp smb smbs smtp smtps telnet tftp
Features: alt-svc AsynchDNS brotli GSS-API HSTS HTTP2 HTTPS-proxy IDN IPv6 Kerberos Largefile libz NTLM NTLM_WB PSL SPNEGO SSL threadsafe TLS-SRP UnixSockets zstd

$ http --version
3.2.1
```