LoginSignup
1
1

More than 3 years have passed since last update.

TypeScriptとGraphQLで'Hello,World!'をしよう!🌏

Last updated at Posted at 2020-01-10

この記事を書くにあたって以下の動画を参考にしました。
ぶっちゃけ僕の記事よりこの動画みた方が分かりやすいです😂
https://youtu.be/8yZImm2A1KE

でも英語になるので、日本語が良いって方は記事を読み進めてください😁
なるべく初学者でも分かるように書きます✍️

今回のプロジェクトはGitHubに公開してます😎
https://github.com/yuuta-wata/hello-app

開発環境

MacOS Catalina v.10.15.1

好きな名前でプロジェクトを作る 📁

まずは適当なディレクトリでプロジェクトを作りましょう!
今回はhello-appというプロジェクトにします🥳

package.jsonを作成

これがないと始まりません!最初に作りましょう!😎
ターミナルで下記のコマンドを実行します、そうすると、、、

// npmでも良いよ🙆‍♂️
% yarn init -y

packaje.json作成!!!下記のようなファイルが作成されていると思います!
でもパッケージがインストールされていないので、必要なパッケージをインストールします!

packaje.json
{
  "name": "hello-app",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT"
}

ターミナルで下記のコマンドを実行してください👇

% yarn add apollo-server-express express graphql reflect-metadata type-graphql
% yarn add -D @types/express @types/graphql @types/node nodemon ts-node typescript

各パッケージの説明は長くなるので省きますが、簡単に説明すると、graphql、type-graphql、@types/graphqlはTypeScriptで使いやすいGraphQLをインストールしてて、apollo-server-express、express、@types/expressはサーバーを立ててAPI通信するためのパッケージなんだなぁ〜くらいに思ってて大方間違いではないはずです。
そもそも僕があまり理解していないのは内緒です🤭

そしてpackage.jsonがこんな感じになるはずです!
"scripts"は手動で追加してください、これでyarn startコマンドでサーバー起動が可能になります。
各バージョンはインストールした時期によって変わるので、気にしなくてOK!

{
  "name": "hello-app",
  "version": "1.0.0",
  "main": "index.js",
  "license": "MIT",
  "dependencies": {
    "apollo-server-express": "^2.9.16",
    "express": "^4.17.1",
    "graphql": "^14.5.8",
    "reflect-metadata": "^0.1.13",
    "type-graphql": "^0.17.6"
  },
  "devDependencies": {
    "@types/express": "^4.17.2",
    "@types/graphql": "^14.5.0",
    "@types/node": "^13.1.6",
    "nodemon": "^2.0.2",
    "ts-node": "^8.6.0",
    "typescript": "^3.7.4"
  },
  "scripts": {
    "start": "nodemon --exec ts-node src/index.ts"
  }
}

tsconfig.jsonを作成

TypeScriptなのでコンパイラが必要です、そのためのjsonファイルを作成します!
ターミナルコマンドで下記のコマンドを実行すると、、、👇

% tsc --init

tsconfig.jsonファイル作成!下記のようなファイルが作成されます。これを、、、

tsconfit.json
{
  "compilerOptions": {
    /* Basic Options */
    // "incremental": true,                   /* Enable incremental compilation */
    "target": "es5",                          /* Specify ECMAScript target version: 'ES3' (default), 'ES5', 'ES2015', 'ES2016', 'ES2017', 'ES2018', 'ES2019' or 'ESNEXT'. */
    "module": "commonjs",                     /* Specify module code generation: 'none', 'commonjs', 'amd', 'system', 'umd', 'es2015', or 'ESNext'. */
    // "lib": [],                             /* Specify library files to be included in the compilation. */
    // "allowJs": true,                       /* Allow javascript files to be compiled. */
    // "checkJs": true,                       /* Report errors in .js files. */
    // "jsx": "preserve",                     /* Specify JSX code generation: 'preserve', 'react-native', or 'react'. */
    // "declaration": true,                   /* Generates corresponding '.d.ts' file. */
    // "declarationMap": true,                /* Generates a sourcemap for each corresponding '.d.ts' file. */
    // "sourceMap": true,                     /* Generates corresponding '.map' file. */
    // "outFile": "./",                       /* Concatenate and emit output to single file. */
    // "outDir": "./",                        /* Redirect output structure to the directory. */
    // "rootDir": "./",                       /* Specify the root directory of input files. Use to control the output directory structure with --outDir. */
    // "composite": true,                     /* Enable project compilation */
    // "tsBuildInfoFile": "./",               /* Specify file to store incremental compilation information */
    // "removeComments": true,                /* Do not emit comments to output. */
    // "noEmit": true,                        /* Do not emit outputs. */
    // "importHelpers": true,                 /* Import emit helpers from 'tslib'. */
    // "downlevelIteration": true,            /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */
    // "isolatedModules": true,               /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */

    /* Strict Type-Checking Options */
    "strict": true,                           /* Enable all strict type-checking options. */
    // "noImplicitAny": true,                 /* Raise error on expressions and declarations with an implied 'any' type. */
    // "strictNullChecks": true,              /* Enable strict null checks. */
    // "strictFunctionTypes": true,           /* Enable strict checking of function types. */
    // "strictBindCallApply": true,           /* Enable strict 'bind', 'call', and 'apply' methods on functions. */
    // "strictPropertyInitialization": true,  /* Enable strict checking of property initialization in classes. */
    // "noImplicitThis": true,                /* Raise error on 'this' expressions with an implied 'any' type. */
    // "alwaysStrict": true,                  /* Parse in strict mode and emit "use strict" for each source file. */

    /* Additional Checks */
    // "noUnusedLocals": true,                /* Report errors on unused locals. */
    // "noUnusedParameters": true,            /* Report errors on unused parameters. */
    // "noImplicitReturns": true,             /* Report error when not all code paths in function return a value. */
    // "noFallthroughCasesInSwitch": true,    /* Report errors for fallthrough cases in switch statement. */

    /* Module Resolution Options */
    // "moduleResolution": "node",            /* Specify module resolution strategy: 'node' (Node.js) or 'classic' (TypeScript pre-1.6). */
    // "baseUrl": "./",                       /* Base directory to resolve non-absolute module names. */
    // "paths": {},                           /* A series of entries which re-map imports to lookup locations relative to the 'baseUrl'. */
    // "rootDirs": [],                        /* List of root folders whose combined content represents the structure of the project at runtime. */
    // "typeRoots": [],                       /* List of folders to include type definitions from. */
    // "types": [],                           /* Type declaration files to be included in compilation. */
    // "allowSyntheticDefaultImports": true,  /* Allow default imports from modules with no default export. This does not affect code emit, just typechecking. */
    "esModuleInterop": true,                  /* Enables emit interoperability between CommonJS and ES Modules via creation of namespace objects for all imports. Implies 'allowSyntheticDefaultImports'. */
    // "preserveSymlinks": true,              /* Do not resolve the real path of symlinks. */
    // "allowUmdGlobalAccess": true,          /* Allow accessing UMD globals from modules. */

    /* Source Map Options */
    // "sourceRoot": "",                      /* Specify the location where debugger should locate TypeScript files instead of source locations. */
    // "mapRoot": "",                         /* Specify the location where debugger should locate map files instead of generated locations. */
    // "inlineSourceMap": true,               /* Emit a single file with source maps instead of having a separate file. */
    // "inlineSources": true,                 /* Emit the source alongside the sourcemaps within a single file; requires '--inlineSourceMap' or '--sourceMap' to be set. */

    /* Experimental Options */
    // "experimentalDecorators": true,        /* Enables experimental support for ES7 decorators. */
    // "emitDecoratorMetadata": true,         /* Enables experimental support for emitting type metadata for decorators. */

    /* Advanced Options */
    "forceConsistentCasingInFileNames": true  /* Disallow inconsistently-cased references to the same file. */
  }
}

こうします!各オプションの詳しい内容は公式ドキュメントを読んでください。👨‍💻
英語になるので、Google翻訳を使って読んでください!日本語が怪しいけど、大体分かります👍

tsconfig.json
{
  "compilerOptions": {
    "target": "es6",
    "module": "commonjs",
    /*すべての厳密な型チェックオプションを有効にします。*/
    "strict": true /* Enable all strict type-checking options. */,
    "esModuleInterop": true,
    /* Experimental Options */
    /*ES7デコレータの実験的なサポートを有効にします。*/
    "experimentalDecorators": true /* Enables experimental support for ES7 decorators. */,
    /*デコレータのタイプメタデータを送信するための実験的なサポートを有効にします。*/
    "emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */,
    /* Advanced Options */
    /*同じファイルへの一貫性のないケース参照を禁止します*/
    "forceConsistentCasingInFileNames": true /* Disallow inconsistently-cased references to the same file. */
  },
  /*コンパイルしないファイルを指定*/
  "exclude": ["node_modules"],
  /*コンパイルするファイルを指定、これを指定しない場合はexcludeで指定したファイル以外全てをコンパイルする*/
  "include": ["./src/**/*tsx", "./src/**/*.ts"]
}

準備は整った!!!

これで準備は整いました、src/index.tsを作成し、コードを書いていきましょう!
プロジェクト構成はこうなります📂

hello-app
  |__node_modules
  |__src
  |   |__index.ts
  |__.gitgnore ←このファイルは任意、分からない方はググってください
  |__package.json
  |__tsconfig.json
  |__yarn.lock ←npm使ってたらこのファイルは無い

index.tsのコードはこうなります✍️

src/index.ts
import 'reflect-metadata';
import { ApolloServer } from 'apollo-server-express';
import Express from 'express';
import { buildSchema, Resolver, Query } from 'type-graphql';
// スキーマ
@Resolver()
class HelloResolver {
  // クエリhelloを作成
  @Query(() => String)
  async hello() {
    return 'Hello,World¡';
  }
}

const main = async () => {
  // スキーマをビルド
  const schema = await buildSchema({
    resolvers: [HelloResolver]
  });
  // インスタンス作成(スキーマを代入している)
  const apolloServer = new ApolloServer({ schema });
  // インスタンス作成
  const app = Express();
  // アポロサーバーにExpressを使う
  apolloServer.applyMiddleware({ app });
  // 4000ポートで起動 4000じゃなくてもいい
  app.listen(4000, () => {
    console.log('サーバー起動🚀 http://localhost:4000/graphql');
  });
};

main();

サーバーを起動させる

ターミナルで yarn start を実行するとサーバーが起動して、URLが表示されるはずです、それを⌘+クリックしてください!
こんな感じ👇

% yarn start
yarn start
yarn run v1.19.1
$ nodemon --exec ts-node src/index.ts
[nodemon] 2.0.2
[nodemon] to restart at any time, enter `rs`
[nodemon] watching dir(s): *.*
[nodemon] watching extensions: ts,json
[nodemon] starting `ts-node src/index.ts`
サーバー起動🚀 http://localhost:4000/graphql ←こいつを⌘+クリック

クリックするとこのページに飛ぶはずです、ここでクエリhelloを実行するとHello,Worldが返ってきます!
こんな感じになれば成功です!🎉😆
スクリーンショット 2020-01-11 4.56.02.png

終わり

お疲れさまでした🍵ここから公式ドキュメントを読んだり、ググったりして、色んな機能を実装すると面白いですので、いじくり回して遊んでみてください!

また次の記事で会いましょう🥳

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1