ติดตั้ง GraphQL บน Firebase Cloud Functions
Table of Contents
โลกหมุนเร็วขึ้นทุกวัน จากที่ RESTful API เคยยืนหนึ่งไร้เทียมทานทุกวันนี้ก็มีคนเสนอแนวคิดใหม่ๆในการสร้างระบบ API หนึ่งในผู้เล่นที่น่าสนใจที่สุดคนหนึ่งก็คือ GraphQL ด้วยเครื่องมือที่มีให้ครบทั้งฝั่ง client และ server แถมยังมีวิธีการเรียกใช้และจัดการที่น่าสน ผมเลยอดไม่ได้ที่จะขอลอง แต่ถ้าจะไปติดตั้งบน server ก็คงธรรมดาไปใช่ไหมล่ะ บทความนี้ผมจะพาใช้มันบน BaaS อย่าง Firebase Cloud Functions กัน
GraphQL #
GraphQL เป็นตัวกลางที่ช่วยจัดการข้อมูลที่คุณมีอยู่ไม่ว่าจะเป็น database หรือเป็น API อื่นๆ ซึ่งข้อมูลพวกนี้จะถูกเรียกได้ด้วย query language ของ GraphQL เองและถูกกำหนดใน Schema ทุกอย่าง ทำให้คุณไม่ต้องไปเขียน document เพราะ GraphQL จะอ่านทุกอย่างจาก Schema แล้วมาสร้าง document หรือ playground ให้คุณและคนอื่นๆในทีมสามารถสื่อสารกันได้สะดวกมากขึ้น
Firebase Cloud Functions #
Cloud Functions คือบริการหนึ่งใน Firebase ที่จะให้ความช่วยเหลือในด้านการทำ server แต่ไม่ใช่ server ที่ run ตลอดเวลาแบบที่เราใช้กันทั่วไป มันคือ server ที่จะทำงานเฉพาะ function ที่เราเขียนเอาไว้ แล้วก็ทำเฉพาะเวลาที่มี trigger ด้วย เช่น HTTP Request, มีการเขียนหรือแก้ไขใน FireStore Database เป็นต้น ซึ่งการทำงานแบบนี้บางคนก็มองว่ามันไม่เปลืองทรัพยากรดี เพราะทำงานเฉพาะเวลาที่มีคนเรียกใช้แล้วก็ปิดตัวไป ไม่ต้องรันเครื่องเอาไว้กินตังค์ทั้งเดือน บริการนี้เลยเหมาะกับงานอะไรที่ทำครั้งเดียวแล้วจบ ไม่มีการรันทิ้งไว้นานๆ
เตรียมพร้อม #
เข้าไปสร้าง Project ใหม่ที่ Firebase เอาไว้ครับผม ใครที่มี Google Account อยู่แล้วก็สามารถเข้าใช้งานได้เลย และไม่ต้องห่วงครับเนื้อหาในบทความนี้ อยู่ใน Free tier ของ Firebase อยู่แล้วคุณไม่จำเป็นต้องผูกบัตรใดๆ

เสร็จแล้วต่อไปนี้เราก็จะเปิด Terminal กันเลยครับ
วิธีการติดตั้ง #
ในบทความนี้ผมจะขอพูดถึงการติดตั้งคร่าวๆเท่านั้นนะครับ จะไม่มีการลงลึกถึงการใช้งานหรือการเรียกใช้ Firestore database อะไรแบบนั้นนะครับ มาดูกันก่อนว่าในการติดตั้งเราจะใช้อะไรกันบ้างครับ
- Express.js เนื่องจากเราจะใช้งาน Trigger ที่เป็น
https.onRequest()
สำหรับคนที่ใช้ NodeJS จะมีเครื่องมือไหนคุ้นมือเท่า Express อีกแล้วล่ะครับ - apollo-server-express ตัว Apollo Server ก็คือ GraphQL Server เจ้านึงครับ ซึ่งเขาก็มีทั้งขายบริการด้วย แล้วก็ Opensource ตัว server ให้เราไปติดตั้งเองได้ด้วย ซึ่งตัวนี้ Apollo Community เขาก็สร้างตัว Integration ระหว่าง Express กับ GraphQL ให้เราแล้วงานนี้เลยสบาย
อธิบายเครื่องมือคร่าวๆแล้วเดี๋ยวมาเริ่มกันเลยดีกว่า ใครที่ยังไม่มี Node
ให้ไปติดตั้งให้เรียบร้อยก่อนนะครับ
- เริ่มจากติดตั้ง Firebase CLI ก่อนครับ
npm install -g firebase-tools
- แล้วก็ทำการ login ใน terminal เลยนะครับ คำสั่งนี้จะเปิด web browser ขึ้นมาให้เรา login Google Account ที่เราพึ่งสร้าง project ไปเมื่อสักครู่นั่นแหละครับ
firebase login
- สร้างโฟลเดอร์ของ project นี้กันครับ
mkdir sample-gql-cf && cd sample-gql-cf
- Initialize ตัว project ด้วยคำสั่ง
firebase init
คำถามแรกในคำสั่งนี้คือ เราต้องการให้ตัว Firebase CLI สร้างโฟลเดอร์เตรียมไว้สำหรับ feature ไหนบ้าง บทความนี้เราใช้แค่ Functions ครับ
❯◉ Functions: Configure and deploy Cloud Functions
กด Space
เพื่อเลือกแล้วค่อย Enter
เพื่อยืนยันนะครับ หลังจากนั้นก็เลือกชื่อ Project ที่เราสร้างไว้ตอนแรกครับ ผมเลือกไว้แบบนี้นะครับ

หลังจากเสร็จจากตรงนี้เราจะได้ไฟล์ชื่อ firebase.json
กับโฟลเดอร์ชื่อ functions
นะครับ
- ติดตั้ง package ที่ต้องใช้
cd functions
npm install express apollo-server-express graphql
- เปิด Code Editor ของคุณขึ้นมาได้เลยครับ บทความนี้ผมจะใช้ Visual Studio Code นะครับ
code .
ในโฟลเดอร์ functions จะประกอบไปด้วย
node_modules
อันนี้เราไม่แตะต้องมันครับ ปล่อยมันหนักอยู่ตรงนั้นแหละ.eslintrc.json
ใครที่เลือกใช้ ESLint ไฟล์นี้จะถูกสร้างขึ้นมาครับ สามารถเข้าไปปรับแต่งได้ตามใจชอบซึ่งอันนี้ไม่กล่าวถึงนะ.gitignore
เอาไว้บอกให้ git มองข้ามไฟล์หรือโฟลเดอร์ไหนบ้าง โดยเฉพาะnode_modules
อย่าได้เผลอเอามันติดไปด้วยนะpackage.json
และpackage-lock.json
เอาไว้ config ตัว package ที่เราใช้ครับ แต่จริงๆเรา install มาหมดแล้วก็ไม่ต้องไปแก้ไขอะไรหรอกindex.js
อันนี้ได้แก้แน่นอนครับ ศูนย์กลางของ project อยู่ที่นี่
- สร้างโฟลเดอร์ใหม่แล้วก็ไฟล์ข้างในดังนี้ครับ
graphql
- schema.js
- resolver.js
- server.js
schema.js
จะเขียนกำหนด schema ของ api เอาไว้นะครับว่าจะมีอะไรบ้าง ซึ่งตัวอย่างนี้จะมีแค่ Query อย่างเดียว คือhi
ที่จะ return ค่าString
กลับไปให้ client ที่เรียกมัน
const { gql } = require('apollo-server-express');
const schema = gql`
type Query {
hi: String
}
`;
module.exports = schema;
resolver.js
หลังจากเขียน schema แล้วresovler
ก็คือส่วนที่เป็น function การทำงานจริงๆครับ ไม่ว่าจะเป็นการไป query เอา data จาก database หรือจะคำนวณอะไรก็แล้วแต่ มันจะอยู่ใน Resolver นี่แหละ ตัวอย่างนี้ผมก็ให้ functionhi
return string โง่ๆกลับไปหนึ่งชุดคือHello from GraphQL
นะครับ
const resolverFunctions = {
Query: {
hi: () => 'Hello from GraphQL'
}
};
module.exports = resolverFunctions;
server.js
ตั้งค่าตัว apollo server กันตรงนี้ครับ ทั้งschema
และresolver
จะถูกเรียกมาไว้ในตัวApolloServer
ด้วย แน่นอนว่าผมจะ enableplayground
เอาไว้ครับ สำหรับทดสอบการใช้งานกัน และเพื่อให้ playground ทำการ call ไปยัง server ได้ก็ต้อง enablecors
ไว้ด้วยเช่นกัน
const express = require('express');
const { ApolloServer } = require('apollo-server-express');
const schema = require('./schema');
const resolvers = require('./resolvers');
const gqlServer = () => {
const app = express();
const apolloServer = new ApolloServer({
typeDefs: schema,
resolvers,
introspection: true,
playground: true
});
apolloServer.applyMiddleware({ app, path: '/', cors: true });
return app;
}
module.exports = gqlServer
- กลับมาที่
index.js
เราจะเอาgqlServer
ซึ่งเป็นapollo-server
ที่รวมร่างกับexpress
แล้วมาใช้ตอนที่ถูก trigger ด้วยhttps.onRequest()
นั่นเอง
const { https } = require('firebase-functions');
const gqlServer = require('./graphql/server');
const server = gqlServer();
const api = https.onRequest(server);
module.exports = {
api
}
- ทดลอง run ในเครื่องของเราดูก่อนครับ โดยกลับไปที่โฟลเดอร์
functions
ใน terminal แล้วใช้คำสั่ง
npm run serve
ถ้าไม่มีปัญหาอะไรเราจะได้ url มาครับ อย่างของผมเป็น http://localhost:5000/sample-gql-cf/us-central1/api เมื่อเอาไปเปิดบน browser ก็จะได้เห็น playground ที่สวยงาม ผมลอง query ตามที่เขียนไปดูเราก็จะได้ response กลับมาว่า “Hello from GraphQL” เรียบร้อย

- สุดท้ายทำการ deploy ไปยัง Firebase ด้วยคำสั่ง
npm run deploy
เรียบร้อยแล้วเราก็จะได้ url ของจริงมาครับ ก็ลองเอาไปเปิดบน browser ได้เลยเช่นกันแต่ ท่านอาจจะเจอ error แบบนี้

ไม่ต้องตกใจครับ path มันผิดแค่พิมพ์คำว่า /api
ต่อท้ายเข้าไปก็จะจบครับ

ตัวอย่าง code #
https://github.com/clonezer/gql-cf-sample
การใช้ Cloud Functions ถ้าจะเอาไปใช้งานจริงๆ ต้องศึกษาถึงเรื่อง cost ที่อาจจะเกิดอย่างจริงจังด้วยนะครับ เพราะถึงมันจะช่วยเราประหยัดได้แต่ในบางกรณีมันอาจจะแพงกว่าเช่า server เอาก็ได้ สำหรับใครที่เอามาทดลองเล่นๆ หรือเป็น api ที่ใช้กันภายเล็กๆก็น่าเอามาลองใช้ดูครับ