สร้าง API ด้วยฟังก์ชัน Gatsby

เผยแพร่แล้ว: 2022-03-10
สรุปโดยย่อ ↬ ในบทช่วยสอนนี้ Paul Scanlon อธิบายวิธีสร้าง API โดยใช้ฟังก์ชัน Gatsby และสิ่งที่คุณต้องคำนึงถึงเมื่อปรับใช้กับ Gatsby Cloud

คุณอาจเคยได้ยินเกี่ยวกับ Serverless Functions แต่ถ้าไม่เคย Serverless Functions จะมีฟังก์ชันที่มักเกี่ยวข้องกับเทคโนโลยีฝั่งเซิร์ฟเวอร์ที่สามารถนำไปใช้ควบคู่ไปกับโค้ด front-end ได้โดยไม่ต้องไปยุ่งกับโครงสร้างพื้นฐานฝั่งเซิร์ฟเวอร์

ด้วยโค้ดฝั่งเซิร์ฟเวอร์และฝั่งไคลเอ็นต์ร่วมกันในฐานโค้ดเดียวกัน นักพัฒนาส่วนหน้าเช่นฉันจึงสามารถขยายขอบเขตของสิ่งที่เป็นไปได้โดยใช้เครื่องมือที่พวกเขารู้จักและชื่นชอบอยู่แล้ว

ข้อจำกัด

การอยู่ร่วมกันเป็นสิ่งที่ยอดเยี่ยม แต่มีอย่างน้อยสองสถานการณ์ที่ฉันพบโดยที่การใช้ฟังก์ชันแบบไร้เซิร์ฟเวอร์ในลักษณะนี้ไม่เหมาะกับงานที่ทำอยู่เลย พวกเขามีดังนี้:

  1. ส่วนหน้าไม่รองรับฟังก์ชั่น Serverless
  2. จำเป็นต้องมีฟังก์ชันเดียวกันโดยส่วนหน้ามากกว่าหนึ่งส่วน

เพื่อช่วยอธิบายบริบท ต่อไปนี้คือตัวอย่างหนึ่งของทั้งจุดที่ 1 และ 2 ที่มีชื่อด้านบน ฉันดูแลโครงการโอเพ่นซอร์สที่เรียกว่า MDX Embed คุณจะเห็นจากเว็บไซต์เอกสารว่าไม่ใช่เว็บไซต์ Gatsby มันถูกสร้างขึ้นโดยใช้ Storybook และ Storybook ด้วยตัวมันเองไม่มีความสามารถของ Serverless Function ฉันต้องการใช้เงินบริจาค "จ่ายในสิ่งที่คุณต้องการ" เพื่อช่วยสนับสนุนโครงการนี้ และฉันต้องการใช้ Stripe เพื่อเปิดใช้งานการชำระเงินที่ปลอดภัย แต่ไม่มี "แบ็กเอนด์" ที่ปลอดภัย สิ่งนี้จะเป็นไปไม่ได้

ด้วยการแยกฟังก์ชันการทำงานนี้ออกเป็น API ที่สร้างด้วย Gatsby Functions ฉันสามารถบรรลุสิ่งที่ต้องการด้วย MDX Embed และยังใช้ฟังก์ชันเดิมซ้ำและเปิดใช้งานฟังก์ชัน "จ่ายสิ่งที่คุณต้องการ" สำหรับบล็อกของฉัน

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับวิธีที่ฉันทำได้ที่นี่: สร้างรายได้จากซอฟต์แวร์โอเพ่นซอร์สด้วยฟังก์ชัน Gatsby และ Stripe

เมื่อถึงจุดนี้การใช้ Gatsby Functions สามารถทำหน้าที่เป็น Back end สำหรับ front end หรือ BFF และการพัฒนาในลักษณะนี้คล้ายกับการพัฒนา API ( Application Programming Interface ) มากกว่า

โค้ดส่วนหน้าใช้ APIs เพื่อจัดการกับสิ่งต่างๆ เช่น การเข้าสู่ระบบ การดึงข้อมูลตามเวลาจริง หรืองานรักษาความปลอดภัยที่ไม่ได้รับการจัดการอย่างเหมาะสมโดยเบราว์เซอร์เพียงอย่างเดียว ในบทช่วยสอนนี้ ฉันจะอธิบายวิธีสร้าง API โดยใช้ Gatsby Functions และปรับใช้กับ Gatsby Cloud

เพิ่มเติมหลังกระโดด! อ่านต่อด้านล่าง↓

เช็คไฟลท์ก่อนบิน

ฟังก์ชัน Gatsby จะทำงานเมื่อปรับใช้กับ Gatsby Cloud หรือ Netlify และในบทช่วยสอนนี้ ฉันจะอธิบายวิธีปรับใช้กับ Gatsby Cloud ดังนั้นคุณจะต้องสมัครใช้งานและสร้างบัญชีฟรีก่อน

คุณจะต้องมีบัญชี GitHub, GitLab หรือ BitBucket นี่คือวิธีที่ Gatsby Cloud อ่านโค้ดของคุณแล้วสร้าง "ไซต์" ของคุณ หรือในกรณีนี้คือ API

สำหรับจุดประสงค์ของบทช่วยสอนนี้ ฉันจะใช้ GitHub หากคุณต้องการก้าวไปข้างหน้า สามารถดูรหัส API สาธิตที่เสร็จแล้วได้ใน GitHub ของฉัน

เริ่มต้น

สร้าง dir ใหม่ที่ไหนสักแห่งบนไดรฟ์ในเครื่องของคุณและเรียกใช้สิ่งต่อไปนี้ในเทอร์มินัลของคุณ สิ่งนี้จะตั้งค่าเริ่มต้น package.json

 npm init -y

การพึ่งพา

พิมพ์ข้อมูลต่อไปนี้ในเทอร์มินัลของคุณเพื่อติดตั้งการพึ่งพาที่จำเป็น

 npm install gatsby react react-dom

หน้า

เป็นไปได้ว่า API ของคุณจะไม่มี "หน้า" แต่เพื่อหลีกเลี่ยงไม่ให้เห็น คำเตือนหน้าเริ่มต้นที่หายไป ของ Gatsby เมื่อคุณไปที่ URL รูทในเบราว์เซอร์ ให้เพิ่มข้อมูลต่อไปนี้ใน src/pages/index.js และ src/pages/404.js เอส

 //src/pages/index.js & src/pages/404.js export default () => null;

API

เพิ่มสิ่งต่อไปนี้ใน src/api/my-first-function.js

ฉันจะอธิบายในภายหลังว่า 'Access-Control-Allow-Origin', '*' หมายถึงอะไร แต่โดยย่อ จะทำให้แน่ใจว่า API ของคุณจากต้นทางอื่นจะไม่ถูกบล็อกโดย CORS

 //src/api/my-first-function.js export default function handler(req, res) { res.setHeader('Access-Control-Allow-Origin', '*'); res.status(200).json({ message: 'A ok!' }); }

สคริปต์

เพิ่มสิ่งต่อไปนี้ใน package.json

 //package.json ... "scripts": { "develop": "gatsby develop", "build": "gatsby build" }, ...

เริ่มเซิร์ฟเวอร์การพัฒนา Gatsby

ในการหมุนเซิร์ฟเวอร์การพัฒนา Gatsby ให้รันสิ่งต่อไปนี้ในเทอร์มินัลของคุณ

 npm run develop

ขอจากเบราว์เซอร์

เมื่อเซิร์ฟเวอร์การพัฒนาของ Gatsby ทำงาน คุณสามารถเข้าไปที่ http://localhost:8000/api/my-first-function และเนื่องจากเป็นคำขอ GET ธรรมดา คุณควรเห็นสิ่งต่อไปนี้ในเบราว์เซอร์ของคุณ

 { "message": "A ok!" }

ยินดีด้วย

คุณเพิ่งพัฒนา API โดยใช้ฟังก์ชัน Gatsby

ปรับใช้

หากคุณเห็นการตอบสนองข้างต้นในเบราว์เซอร์ของคุณ ถือว่าปลอดภัยที่จะถือว่าฟังก์ชันของคุณทำงานอย่างถูกต้องในเครื่อง ในขั้นตอนต่อไปนี้ ฉันจะอธิบายวิธีปรับใช้ API ของคุณกับ Gatsby Cloud และเข้าถึงโดยใช้คำขอ HTTP จาก CodeSandbox

กดรหัสไปที่ Git

ก่อนที่จะพยายามปรับใช้กับ Gatsby Cloud คุณจะต้องพุชรหัสของคุณไปยังผู้ให้บริการ Git ที่คุณเลือก

แกสบี้ คลาวด์

ลงชื่อเข้าใช้บัญชี Gatsby Cloud ของคุณและมองหาปุ่มสีม่วงขนาดใหญ่ที่ระบุว่า "เพิ่มไซต์ +"

สกรีนช็อตของไซต์ Gatsby Cloud Add
เพิ่มไซต์ใน Gatsby Cloud (ตัวอย่างขนาดใหญ่)

ในขั้นตอนต่อไป คุณจะถูกขอให้นำเข้าจากที่เก็บ Git หรือ เริ่มต้นจากเทมเพลต เลือก Import from Git Repository แล้วกด next

สกรีนช็อตเลือกการนำเข้าจากที่เก็บ Git
เลือกนำเข้าจากที่เก็บ Git (ตัวอย่างขนาดใหญ่)

ตามที่กล่าวไว้ข้างต้น Gatsby Cloud สามารถเชื่อมต่อกับ GitHub, GitLab หรือ Bitbucket เลือกผู้ให้บริการ Git ที่คุณต้องการแล้วกด next

สกรีนช็อตของการเลือกผู้ให้บริการ Gatsby Cloud Git
เลือกจากผู้ให้บริการ Git ที่คุณต้องการ (ตัวอย่างขนาดใหญ่)

ด้วยการเชื่อมต่อผู้ให้บริการ Git ของคุณ คุณสามารถค้นหาที่เก็บของคุณและตั้งชื่อไซต์ของคุณได้

สกรีนช็อตของการค้นหา Gatsby Cloud สำหรับไซต์จากผู้ให้บริการ Git
ค้นหาไซต์ของคุณจากผู้ให้บริการ Git (ตัวอย่างขนาดใหญ่)

เมื่อคุณเลือกที่เก็บและตั้งชื่อไซต์ของคุณแล้ว ให้กด next

คุณสามารถข้าม "การผสานการทำงาน" และ "การตั้งค่า" ได้ เนื่องจากเราไม่ต้องการสิ่งเหล่านี้

หากทุกอย่างเป็นไปตามแผน คุณควรจะได้เห็นสิ่งที่คล้ายกับภาพหน้าจอด้านล่าง

สกรีนช็อตของไซต์ที่ปรับใช้สำเร็จ
'ไซต์' สร้างและปรับใช้บน Gatsby Cloud ได้สำเร็จ (ตัวอย่างขนาดใหญ่)

คุณจะเห็น URL ที่ลงท้ายด้วย gatsbyjs.io ใกล้ด้านบนทางด้านซ้ายของหน้าจอ ซึ่งจะเป็น URL สำหรับ API ของคุณและฟังก์ชันใดๆ ที่คุณสร้างสามารถเข้าถึงได้โดยการเพิ่ม /api/name-of-function ต่อท้าย URL นี้

เช่น my-first-function.js เวอร์ชันที่ปรับใช้โดยสมบูรณ์สำหรับ API สาธิตของฉันมีดังนี้:

API สาธิต: ฟังก์ชันแรกของฉัน

การทดสอบ API ของคุณ

การเยี่ยมชม URL ของ API ของคุณเป็นสิ่งหนึ่ง แต่โดยทั่วไปแล้วไม่ใช่วิธีที่ API ถูกใช้จริงๆ เป็นการดีที่จะทดสอบ API ของคุณ คุณต้องส่งคำขอไปยังฟังก์ชันจากต้นทางที่ไม่เกี่ยวข้องทั้งหมด

ที่นี่เป็นที่ที่ res.setHeader('Access-Control-Allow-Origin', '*'); มาเพื่อช่วยชีวิต แม้ว่าจะไม่พึงปรารถนาเสมอไปที่จะอนุญาตให้โดเมนใดๆ (เว็บไซต์) เข้าถึงฟังก์ชันของคุณ แต่โดยส่วนใหญ่แล้ว ฟังก์ชันสาธารณะก็เป็นหน้าที่สาธารณะเท่านั้น การตั้งค่าส่วนหัวการควบคุมการเข้าถึงเป็นค่า * หมายความว่าโดเมนใดๆ สามารถเข้าถึงฟังก์ชันของคุณได้ หากไม่มีสิ่งนี้ โดเมนอื่นที่ไม่ใช่โดเมนที่โฮสต์ API ไว้จะถูก CORS บล็อก

นี่คือ CodeSandbox ที่ใช้ my-first-function จาก demo API ของฉัน คุณสามารถแยกข้อมูลนี้และเปลี่ยน URL คำขอของ Axios เพื่อทดสอบฟังก์ชันของคุณได้

CodeSandbox: ฟังก์ชันแรกของฉัน

CodeSandbox: ฟังก์ชันแรกของฉัน
(ตัวอย่างขนาดใหญ่)

เริ่มเล่นสนุกขึ้น

กำลังส่งการตอบกลับจาก API ของคุณที่มี message: "A ok!" ไม่น่าตื่นเต้นเท่าไหร่ ดังนั้นในตอนต่อไป ฉันจะแสดงวิธีสืบค้น GitHub REST API และสร้างการ์ดโปรไฟล์ส่วนบุคคลเพื่อแสดงบนเว็บไซต์ของคุณเองโดยใช้ API ที่คุณเพิ่งสร้างขึ้น และมันจะมีลักษณะเช่นนี้ .

CodeSandbox: การ์ดโปรไฟล์สาธิต

CodeSandbox: การ์ดโปรไฟล์สาธิต
(ตัวอย่างขนาดใหญ่)

การพึ่งพา

ในการใช้ GitHub REST API คุณจะต้องติดตั้ง @octokit/rest package

 npm install @octokit/rest

รับผู้ใช้ GitHub แบบ Raw

เพิ่มสิ่งต่อไปนี้ใน src/api/get-github-user-raw.js

 // src/api/get-github-user-raw.js import { Octokit } from '@octokit/rest'; const octokit = new Octokit({ auth: process.env.OCTOKIT_PERSONAL_ACCESS_TOKEN }); export default async function handler(req, res) { res.setHeader('Access-Control-Allow-Origin', '*'); try { const { data } = await octokit.request(`GET /users/{username}`, { username: 'PaulieScanlon' }); res.status(200).json({ message: 'A ok!', user: data }); } catch (error) { res.status(500).json({ message: 'Error!' }); } }

โทเค็นการเข้าถึง

ในการสื่อสารกับ GitHub REST API คุณจะต้องมีโทเค็นการเข้าถึง คุณสามารถรับสิ่งนี้ได้โดยทำตามขั้นตอนในคู่มือนี้จาก GitHub: การสร้างโทเค็นการเข้าถึงส่วนบุคคล

.env ตัวแปร

เพื่อให้โทเค็นการเข้าถึงของคุณปลอดภัย ให้เพิ่มสิ่งต่อไปนี้ใน . .env.development และ . .env.production

 OCTOKIT_PERSONAL_ACCESS_TOKEN=123YourAccessTokenABC

คุณสามารถอ่านเพิ่มเติมเกี่ยวกับตัวแปรสภาพแวดล้อม Gatsby ได้ในคู่มือนี้จาก Gatsby: ตัวแปรสภาพแวดล้อม

เริ่มการพัฒนาเซิร์ฟเวอร์

อย่างที่คุณทำก่อนเริ่มเซิร์ฟเวอร์การพัฒนา Gatsby โดยพิมพ์ข้อความต่อไปนี้ในเทอร์มินัลของคุณ

 npm run develop

ขอจากเบราว์เซอร์

เมื่อเซิร์ฟเวอร์พัฒนา Gatsby ทำงานอยู่ คุณสามารถไปที่ http://localhost:8000/api/get-github-user-raw และเนื่องจากนี่เป็นคำขอ GET ธรรมดาๆ คุณควรเห็นสิ่งต่อไปนี้ในเบราว์เซอร์ของคุณ ( ฉันได้ลบส่วนหนึ่งของการตอบสนองเพื่อความกระชับ )

 { "message": "A ok!", "user": { "login": "PaulieScanlon", "id": 1465706, "node_id": "MDQ6VXNlcjE0NjU3MDY=", "avatar_url": "https://avatars.githubusercontent.com/u/1465706?v=4", "gravatar_id": "", "url": "https://api.github.com/users/PaulieScanlon", "type": "User", "site_admin": false, "name": "Paul Scanlon", "company": "Paulie Scanlon Ltd.", "blog": "https://www.paulie.dev", "location": "Worthing", "email": "[email protected]", "hireable": true, "bio": "Jamstack Developer / Technical Content Writer (freelance)", "twitter_username": "pauliescanlon", "created_at": "2012-02-23T13:43:26Z", "two_factor_authentication": true, ... } }

นี่คือตัวอย่าง CodeSandbox ของการตอบกลับแบบดิบทั้งหมด

CodeSandbox: การตอบกลับแบบ Raw

CodeSandbox: การตอบกลับแบบ Raw
(ตัวอย่างขนาดใหญ่)

คุณจะเห็นจากด้านบนว่ามีข้อมูลค่อนข้างมากที่ส่งคืนซึ่งฉันไม่ต้องการจริงๆ บิตถัดไปนี้ขึ้นอยู่กับคุณโดยสมบูรณ์ เนื่องจากเป็น API ของคุณ แต่ฉันพบว่ามีประโยชน์ในการจัดการการตอบสนอง GitHub API เล็กน้อย ก่อนที่จะส่งกลับไปยังรหัสส่วนหน้าของฉัน

หากคุณต้องการทำเช่นเดียวกัน คุณสามารถสร้างฟังก์ชันใหม่และเพิ่มสิ่งต่อไปนี้ใน src/api/get-github-user.js

 // src/api/get-github-user.js import { Octokit } from '@octokit/rest'; const octokit = new Octokit({ auth: process.env.OCTOKIT_PERSONAL_ACCESS_TOKEN }); export default async function handler(req, res) { res.setHeader('Access-Control-Allow-Origin', '*'); try { const { data } = await octokit.request(`GET /users/{username}`, { username: 'PaulieScanlon' }); res.status(200).json({ message: 'A ok!', user: { name: data.name, blog_url: data.blog, bio: data.bio, photo: data.avatar_url, githubUsername: `@${data.login}`, githubUrl: data.html_url, twitterUsername: `@${data.twitter_username}`, twitterUrl: `https://twitter.com/${data.twitter_username}` } }); } catch (error) { res.status(500).json({ message: 'Error!' }); } }

คุณจะเห็นจากด้านบนว่าแทนที่จะส่งคืนวัตถุข้อมูลทั้งหมดที่ส่งคืนโดย GitHub REST API ฉันเลือกเฉพาะบิตที่ฉันต้องการ เปลี่ยนชื่อและเพิ่มสองสามบิตก่อนชื่อผู้ใช้และค่า URL สิ่งนี้ทำให้ชีวิตง่ายขึ้นเล็กน้อยเมื่อคุณแสดงข้อมูลในโค้ดส่วนหน้า

นี่คือตัวอย่าง CodeSandbox ของการตอบกลับที่จัดรูปแบบ

CodeSandbox: การตอบสนองที่จัดรูปแบบ

CodeSandbox: การตอบสนองที่จัดรูปแบบ
(ตัวอย่างขนาดใหญ่)

สิ่งนี้คล้ายกันมากกับ Profile Card CodeSandbox จากก่อนหน้านี้ แต่ฉันยังได้พิมพ์ข้อมูลออกมาด้วย เพื่อให้คุณเห็นว่ารายการข้อมูลที่จัดการแต่ละรายการนั้นถูกใช้อย่างไร

เป็นที่น่าสังเกตว่า ณ จุดนี้การสาธิต CodeSandbox ทั้งสี่รายการในบทช่วยสอนนี้กำลังใช้ API สาธิต และไม่มีการสร้างขึ้นโดยใช้ Gatsby หรือโฮสต์บน Gatsby Cloud — เจ๋งมาก!

.env ตัวแปรใน Gatsby Cloud

ก่อนที่คุณจะปรับใช้สองฟังก์ชันใหม่ คุณจะต้องเพิ่มโทเค็นการเข้าถึง GitHub ในส่วนตัวแปรสภาพแวดล้อมใน Gatsby Cloud

สกรีนช็อตของ Gatsby Cloud พร้อมการตั้งค่าไซต์
(ตัวอย่างขนาดใหญ่)

จะไปจากที่นี่ที่ไหน?

ฉันถามคำถามนี้กับตัวเอง โดยทั่วไปแล้วฟังก์ชันแบบไร้เซิร์ฟเวอร์ที่ใช้พูดจะใช้ในคำขอฝั่งไคลเอ็นต์ และแม้ว่าจะไม่เป็นไร ฉันสงสัยว่าสามารถใช้ฟังก์ชันเหล่านี้ในเวลาสร้างเพื่อ "อบ" ข้อมูลลงในหน้าแบบสแตติกได้หรือไม่ แทนที่จะอาศัย JavaScript ที่อาจหรืออาจไม่ถูกปิดใช้งานใน เบราว์เซอร์

…นั่นคือสิ่งที่ฉันทำ

นี่คือแดชบอร์ดข้อมูลประเภทหนึ่งที่ใช้ข้อมูลที่ส่งคืนโดย Gatsby Functions ทั้งที่เวลารันและบิลด์ ฉันสร้างไซต์นี้โดยใช้ Astro และปรับใช้ GitHub Pages

เหตุผลที่ฉันคิดว่านี่เป็นแนวทางที่ดีเพราะฉันสามารถใช้ฟังก์ชันเดิมซ้ำได้ทั้งบนเซิร์ฟเวอร์และในเบราว์เซอร์โดยไม่ต้องทำซ้ำอะไรเลย

ในแอสโตรบิลด์นี้ ฉันไปที่จุดปลายเดียวกันกับที่ API ของฉันเปิดเผยเพื่อส่งคืนข้อมูลที่อบลงในหน้า (เหมาะสำหรับ SEO) หรือดึงข้อมูลในขณะใช้งานโดยเบราว์เซอร์ (เหมาะสำหรับการแสดงข้อมูลสดหรือข้อมูลสดเป็นนาที) .

แดชบอร์ดข้อมูล

ข้อมูลที่แสดงทางด้านซ้ายของไซต์จะถูกร้องขอในเวลาที่สร้างและอบลงในเพจด้วย Astro ขอข้อมูลทางด้านขวาของเพจขณะใช้งานจริงโดยใช้คำขอฝั่งไคลเอ็นต์ ฉันใช้ปลายทางที่แตกต่างกันเล็กน้อยที่เปิดเผยโดย GitHub REST API เพื่อค้นหาบัญชีผู้ใช้ GitHub ที่แตกต่างกันซึ่งสร้างรายการที่แตกต่างกัน

แดชบอร์ดข้อมูล
(ตัวอย่างขนาดใหญ่)

ทุกสิ่งที่คุณเห็นในเว็บไซต์นี้มาจาก API ที่สมบูรณ์กว่าของฉัน ฉันเรียกมันว่า: Paulie API และฉันใช้สำหรับเว็บไซต์จำนวนมาก

Paulie API

Paulie API เช่นเดียวกับ API จากบทช่วยสอนนี้สร้างด้วย Gatsby แต่เนื่องจาก Gatsby สามารถทำหน้าที่เป็นทั้งไซต์และ API ฉันจึงใช้มันเพื่อบันทึกว่าฟังก์ชันทั้งหมดของฉันทำงานอย่างไร และปลายทางแต่ละจุดมีหน้าของตัวเองที่สามารถใช้เป็นแบบโต้ตอบได้ สนามเด็กเล่น… รู้สึกอิสระที่จะได้มองไปรอบ ๆ

Paulie API
(ตัวอย่างขนาดใหญ่)

คุณมีแล้ว Gatsby Functions API ที่สามารถใช้ได้โดยโค้ดฝั่งไคลเอ็นต์หรือฝั่งเซิร์ฟเวอร์ จากเว็บไซต์ที่สร้างด้วยสแต็กเทคโนโลยีใดๆ

ลองใช้ดูและฉันสนใจมากที่จะเห็นสิ่งที่คุณสร้าง รู้สึกอิสระที่จะแบ่งปันในความคิดเห็นด้านล่างหรือมาหาฉันบน Twitter: @PaulieScanlon