ค้นหาเว็บไซต์

API ฝั่งไคลเอนต์-เซิร์ฟเวอร์ที่ปลอดภัยต่อชนิดข้อมูลด้วย TypeScript?


ลองพิจารณาตัวอย่าง การใช้งาน getUser บนฝั่งผู้ใช้จะเป็นประมาณนี้

const user = await getUser(http, { id: '1' })

การทำงานที่ใช้ได้แต่ไม่ปลอดภัยต่อประเภทมากนัก

// ./api.ts - shared interfaces
const endpoint = '/users'
interface Arg { id: string }
interface Resp { name: string }

// ./client-api.ts - client side
import { endpoint, Arg, Resp } from './api.ts'
function getUser(http: HttpClient, arg: Arg): Promise<Resp> {
  return http.get(endpoint, arg)
}

// ./server-api.ts - server side
import { endpoint, Arg, Resp } from './api.ts'
function getUser(db: Db, arg: Arg): Promise<Resp> {
  return db.findById(arg.id)
}
// Additionally it needs to be registered
httpServer.on(endpoint, (params) => getUser(db, params))

ปัญหา: มีโค้ดซ้ำซ้อนมากเกินไป, มีความเป็นไปได้ที่จะจับคู่ Arg จากเมธอดหนึ่งกับ Resp ของอีกเมธอดหนึ่งผิด, หรือจับคู่ endpoint ผิด, หรือ ลืมลงทะเบียน endpoint บนเซิร์ฟเวอร์

การ ใช้งานที่ดีกว่า อาจเป็นแบบโค้ดด้านล่างนี้ แต่อย่างไรก็ตาม มันก็ยังไม่ได้บังคับให้ใช้ endpoint และมีโอกาสที่จะลืมลงทะเบียนตัวจัดการฝั่งเซิร์ฟเวอร์ได้:

// ./api.ts
interface GetUser {
  endpoint: '/users',
  arg:      { id: string },
  resp:     { name: string }
}

type ClientFn<Command> = no idea how to do that, some TS magic
type ServerFn<Command> = no idea how to do that, some TS magic

// ./client-api.ts
const getUser: ClientFn<GetUser> = (http, arg) => http.get(endpoint, arg)

// ./server-api.ts
const getUser: ServerFn<GetUser> = (db, arg) => db.findById(arg.id)
httpServer.on(endpoint, (params) => getUser(db, params))

คุณรู้วิธี ที่ดีกว่า ในการทำสิ่งนั้นไหม? หรือ บางทีอาจมีไลบรารีสร้างโค้ด ใน TypeScript ที่สามารถทำสิ่งนั้นได้?