全端網站設計範例:後端新增 Apollo server
本篇為「全端網站架構」中的後端範例及細節。需先建立專案(請參閱上一篇:全端網站設計範例:後端專案建立)。
由於此專案前後端用 GraphQL 作為 API 的形式,考慮到便利性,前後端都會使用 Apollo 所提供的框架。
主要參閱 Get started with Apollo Server 這篇官方教學文來實做。
安裝 Apollo Server
我們使用 Apollo Server 4
$ npm install @apollo/server graphql
定義 GraphQL schema
$ touch src/schemas.graphql
打開 src/schemas.graphql 並編輯其內容,建立最基本的範例
type Query {
hello: String!
}
定義 Resolver
$ mkdir src/resolvers
$ touch src/resolvers/index.ts
打開 src/resolvers/index.ts 並編輯其內容,建立最基本的範例
export default {
Query: {
hello: (): string => 'world',
},
};
建立 Apollo Server
編輯 src/index.ts
import * as fs from 'fs';
import * as path from 'path';
import { ApolloServer } from '@apollo/server';
import { startStandaloneServer } from '@apollo/server/standalone';
import resolvers from './resolvers';
const server = new ApolloServer({
typeDefs: fs.readFileSync(path.join(__dirname, 'schemas.graphql'), 'utf8'),
resolvers,
});
(async () => {
const { url } = await startStandaloneServer(server, { listen: { port: 5000 } });
console.log(`Server is running at ${url}`);
})();
建立一個 Apollo Server 需要提供 GraphQL schema 的定義,由於 .graphql 無法被直接 import,我們用讀檔的方式把 schema 讀進來。另外再將 resolvers 傳入 Apollo Server,最後呼叫 listen() 啟動伺服器監聽即可。
最後瀏覽 http://localhost:5000 (根據環境變數 PORT 調整),在 Apollo Server v3 後的版本中,會導頁至他們的新版 Query Tool - Apollo Sandbox,就可以進行 Query 的開發操作了(原本 v2 中是用 GraphQL Playground 這個 tool)。
ESLint 可能問題
在 import resolvers from './resolvers' 時遇到 import/no-unresolved
error Unable to resolve path to module './resolvers' import/no-unresolved
參閱 StackOverflow - Using eslint with typescript - Unable to resolve path to module,在 .eslintrc.json 中加上以下程式碼即可解決問題
{
"settings": {
"import/resolver": {
"node": {
"extensions": [".js", ".jsx", ".ts", ".tsx"]
}
}
}
}
在 import resolvers from './resolvers' 時遇到 import/extensions
error Missing file extension "ts" for "./resolvers" import/extensions
參閱 Typescript eslint - Missing file extension “ts” import/extensions,在 .eslintrc.json 中加上以下程式碼即可解決問題
"rules": {
"import/extensions": [
"error",
"ignorePackages",
{
"js": "never",
"jsx": "never",
"ts": "never",
"tsx": "never"
}
]
}
加上 Logging 機制
記錄 Log 在專案中也是必不可少的機制,這裡我們使用 npmlog 來記錄。
$ npm install npmlog
$ npm install -D @types/npmlog
將 index.ts 中的 console.log 替換成 npmlog。
import log from 'npmlog';
server.listen({ port: process.env.PORT || 5000 }).then(({ url }) => {
log.info('index', `Server is running at ${url}`);
});
加上時間
預設的 log 是沒有列出時間的,可以參考這個 issue npmlog - Add option to log timestamp 來加上時間。在 index.ts 中加上以下程式碼
Object.defineProperty(log, 'heading', { get: () => new Date().toUTCString() });
log.headingStyle = { bg: '', fg: 'white' };
印出的 log 就會像是:Wed, 25 Aug 2021 08:39:51 GMT info index Server is running at http://localhost:5000/
參考資料
CHANGELOG
| 日期 | 敘述 |
|---|---|
| 2024-03-04 | 更新使用的工具版本、建立專案細節 |
| 2021-08-20 | 初版 |