Skip to main content
0

สรุปสั้น ๆ

API หรือ Application Programming Interface คือช่องทางที่แอปพลิเคชันใช้ในการติดต่อกัน เพื่อเข้าถึงข้อมูลหรือบริการที่ต้องการเรียกใช้ อย่างในการทำเว็บไซต์หรือแอปพลิเคชันก็จะมี API ที่ Frontend ใช้ติดต่อ Backend อย่างเช่น REST API และ GraphQL

 

เขียนโดย
Sutthinai Boonyingyongchai
MidLevel Software Developer

บทความนี้ตีพิมพ์ และ เผยแพร่เมื่อ 11 สิงหาคม 2566

API Caching

Caching คือการเก็บข้อมูลที่ถูกสร้างหรือคำนวณเอาไว้เพื่อเรียกในครั้งถัด ๆ ไปได้เร็วขึ้น โดยข้อมูลที่เก็บเอาไว้นี้เรียกว่า Cache ซึ่งในกรณีของ API ก็สามารถทำ Caching ได้เหมือนกัน ซึ่งจะช่วยลดการใช้ทรัพยากรเพื่อสร้างหรือคำนวณซ้ำ ๆ ลงได้

ก่อนมี Cache ต้อง Query จาก Database ทุกครั้ง

พอมี Cache เพิ่มมา ลดการ Query จาก Database เหลือแค่ครั้งที่ยังไม่มี Cache เก็บไว้เท่านั้น

Express.js API Caching

เพื่อให้เห็นภาพชัดขึ้น ในบทความนี้เราจะมาลองทำ Caching แบบง่าย ๆ ใน Express.js ที่เป็น Web Framework สำหรับ Node.js ตัวนึง โดเราจะโฟกัสไปที่การสร้าง Cache ให้กับ API แบบไว ๆ

เริ่มจากสร้าง Project ใหม่

โดยใช้คำสั่ง

npm init -y

ใส่ -y เพื่อบอกให้ npm ใช้ Default Config ให้หมดทุกอย่างโดยไม่ต้องถามเรา

จากนั้นติดตั้ง Express ด้วยคำสั่ง

npm install express

แล้วก็ติดตั้ง nodemon ไว้เพื่อความสะดวก จะได้ไม่ต้องรันใหม่เวลาแก้โค้ด

npm install --save-dev nodemon

เสร็จแล้วก็ไปแก้ไฟล์ package.json เพิ่มคำสั่งรันด้วย nodemon เข้าไปใน “scripts” ไฟล์ก็จะออกมาหน้าตาแบบนี้

"start:dev": "nodemon index.js"

สร้างไฟล์ index.js

ใส่โค้ด Express “Hello World” เข้าไป

const express = require('express')
const app = express()
const port = 3000

app.get('/', (req, res) => {
  res.send('Hello World!')
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

เซฟให้เรียบร้อยแล้วรันด้วยคำสั่ง

npm run start:dev

แอปของเราก็จะถูกรันไว้ที่ Port 3000

ลองเปิดดู http://localhost:3000/ ผ่านเบราเซอร์หรือ Postman ก็ได้ จะเจอกับข้อความ “Hello World!”

 

Algorithm อันแสนซับซ้อน

 

สมมติว่ามี API ที่ต้องใช้เวลาประมวลผลนานมาก ๆ กว่าจะส่งข้อมูลกลับออกไปได้ โดยจะใช้การหน่วงด้วย setTimeout เป็นเวลา 5 วินาที สร้างเป็นฟังก์ชันชื่อว่า “getMagicWord” ที่ API ของเราต้องไปเรียกใช้เพื่อรีเทิร์นค่ากลับออกไป

const express = require('express')
const app = express()
const port = 3000

async function getMagicWord(param) {
  await new Promise(resolve => setTimeout(resolve, 5000));
  return 'Hello borntoDev!'
}

app.get('/', async (req, res) => {
  const magicWord = await getMagicWord()
  res.send(magicWord)
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

อย่าลืมกดเซฟโค้ดที่แก้ แล้วลองยิง API ดูอีกครั้งจะเห็นว่าใช้เวลากว่าจะได้รับ Response กลับมา เพิ่มจาก 10 ms ไปเป็น 5.02 s

ใส่ Caching แบบไว ๆ

อย่างที่พูดถึงไปก่อนนี้ว่าการเก็บ Cache ก็คือการเอาข้อมูลที่ถูกสร้างหรือประมวลผลแล้ว เก็บเอาไว้รอการเรียกใช้ในครั้งต่อ ๆ ไปโดยไม่ต้องประมวลผลซ้ำ เพื่อความชัดเจนเราจะสร้าง API ใหม่ GET /with-cache เพื่อทำ Caching

โดยการเก็บข้อมูล Cache นั้นแบบง่ายที่สุดก็คือสร้างเป็นตัวแปรขึ้นมาเก็บค่านั้นไว้ เวลาที่มี Request มาที่ API ก็เช็คว่าตัวแปรนั้นมีค่ารึเปล่าถ้ามีก็ส่งออกไปได้ทันที ถ้าไม่มีถึงค่อยไปเรียกฟังก์ชันที่ใช้ประมวลผลและเซ็ตค่าเก็บเข้าตัวแปร Cache 

 

คราวนี้เปลี่ยนจากข้อความเป็น JSON เพื่อให้ดูข้อมูลง่ายขึ้น โดยที่

  • “requestTimestamp” คือเวลาตอนที่ Server ได้รับ Request
  • “getMagicWordTimestamp” คือเวลาตอนที่ฟังก์ชัน “getMagicWord” ทำงานเสร็จ
  • “magicWord” คือข้อมูลที่เราต้องการ Cache
const express = require('express')
const app = express()
const port = 3000

let myMagicCache = null

async function getMagicWord(param) {
  await new Promise(resolve => setTimeout(resolve, 5000));
  return {
    magicWord: 'Hello borntoDev!',
    getMagicWordTimestamp: new Date().toTimeString()
  }
}

app.get('/', async (req, res) => {
  const magicWord = await getMagicWord()
  res.send(magicWord)
})

app.get('/with-cache', async (req, res) => {
  const requestTimestamp = new Date().toTimeString();

  if (myMagicCache) {
    res.send({ ...myMagicCache, requestTimestamp })
  } else {
    const magicWord = await getMagicWord()
    myMagicCache = magicWord
    res.send({ ...myMagicCache, requestTimestamp })
  }
})

app.listen(port, () => {
  console.log(`Example app listening on port ${port}`)
})

พอเราทำการยิงไปที่ http://localhost:3000/with-cache ในครั้งแรก จะสังเกตได้ว่าใช้เวลารอ 5.02 s โดย “getMagicWordTimestamp” จะเป็นเวลาหลังจาก “requestTimestamp” ประมาณ 5 วินาที

ลองยิงรอบที่ 2 เวลาจะลดลงเหลือเพียง 3 ms

ลองยิ่งรอบที่ 3 อีกซักครั้ง ก็จะเห็นว่าเวลายังเป็น 3 ms

จะเห็นว่าในครั้งที่ 2 และ 3 นั้น ไม่ว่าจะยิงตอนไหน (“requestTimestamp”) ค่าของ Cache ที่ได้ก็เป็นค่าแรกค่าเดิมอยู่ ยืนยันได้จาก “getMagicWordTimestamp” ที่เป็นค่าเดิมตลอดเลยนั่นเอง เพียงแค่นี้ก็พอจะนับได้ว่า API ของเรามีการใช้ Cache แบบเบื้องต้นสุด ๆ แล้วนั่นเอง

คำถามก่อนทำ Cache

ก่อนตัดสินใจลงมือทำ API Caching ลองดู 3 คำถามสั้น ๆ นี้ น่าจะช่วยให้มีแนวทางการพัฒนาที่ชัดเจนขึ้นได้ 

1) Cache อะไร ? 

เพราะว่าการเก็บ Cache ก็ต้องใช้ทรัพยาของระบบเหมือนกัน เราควรดูจากความสำคัญของ API แต่ละเส้น รวมถึงความถี่ในการถูกเรียกใช้งาน จะได้ไม่ต้องเก็บ Cache ในเส้นที่ไม่จำเป็น

 

2) Cache ที่ไหน ?

เมื่อเราได้ลิสต์ของ API ที่เราต้องการ Cache แล้ว ก็มาดูกันต่อว่าเราจะเก็บข้อมูลไว้ที่ไหนดี 

หลัก ๆ แล้วจะมีแบบ 

  • Memory: ก็คือเก็บใน RAM เพื่อความเร็วในการเรียกใช้
  • Disk: ก็คือเก็บลง Database เพื่อให้มีพื้นที่สำหรับเก็บข้อมูลใหญ่ ๆ

 

3) Cache ยังไง ?

สุดท้ายที่เราต้องคิดก็คือจะเก็บ Cache ยังไง ให้เหมาะกับระบบเราที่สุด

  • ขนาด/จำนวน: ของ Cache มีผลโดยตรงต่อ Server ของเรา ถ้าเก็บ Cache ขนาดใหญ่หรือเยอะเกินไป ก็ส่งผลต่อความเร็วในการเรียก Cache นั้นออกมาใช้งาน และต้องใช้ทรัพยากรของระบบเยอะในการเก็บ Cache
  • การหมดอายุ: จะทำให้ Cache ที่เก่าถึงจุดนึงถูกลบออกไป เพื่อให้ระบบสร้างข้อมูลใหม่มาใส่แทน ซึ่งจะช่วยทั้งเรื่องความสดใหม่ของข้อมูล และลดการเก็บ Cache เก่า ๆ เอาไว้โดยไม่จำเป็นลงได้

 

หวังว่าบทความนี้จะช่วยให้ได้รู้จักกับ API Caching มากขึ้นนะครับ

ระบบฝึกทักษะ การเขียนโปรแกรม

ที่พร้อมตรวจผลงานคุณ 24 ชั่วโมง

  • โจทย์ปัญหากว่า 200 ข้อ ที่รอท้าทายคุณอยู่
  • รองรับ 9 ภาษาโปรแกรมหลัก ไม่ว่าจะ Java, Python, C ก็เขียนได้
  • ใช้งานได้ฟรี ! ครบ 20 ข้อขึ้นไป รับ Certificate ไปเลย !!
เข้าใช้งานระบบ DevLab ฟรี !เรียนรู้เพิ่มเติม

เรียนรู้ไอที “อัพสกิลเขียนโปรแกรม” จากตัวจริง
ปั้นให้คุณเป็น คนสายไอทีระดับมืออาชีพ

BorntoDev

Author BorntoDev

BorntoDev Co., Ltd.

More posts by BorntoDev

เราใช้คุกกี้เพื่อพัฒนาประสิทธิภาพ และประสบการณ์ที่ดีในการใช้เว็บไซต์ของคุณ คุณสามารถศึกษารายละเอียดได้ที่ นโยบายความเป็นส่วนตัว และสามารถจัดการความเป็นส่วนตัวเองได้ของคุณได้เองโดยคลิกที่ ตั้งค่า

ตั้งค่าความเป็นส่วนตัว

คุณสามารถเลือกการตั้งค่าคุกกี้โดยเปิด/ปิด คุกกี้ในแต่ละประเภทได้ตามความต้องการ ยกเว้น คุกกี้ที่จำเป็น

ยอมรับทั้งหมด
จัดการความเป็นส่วนตัว
  • คุกกี้ที่จำเป็น
    เปิดใช้งานตลอด

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

  • คุกกี้สำหรับการติดตามทางการตลาด

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

บันทึกการตั้งค่า