คู่มือคู่มือ

goldprice.dev คำนวณราคาทองคำเป็นสกุลเงินท้องถิ่นอย่างไร

goldprice.dev ผสานราคาทองคำในสกุลดอลลาร์สหรัฐเข้ากับอัตราแลกเปลี่ยนจาก exchangerate.dev เพื่อให้บริการราคาทองคำในสกุลเงินท้องถิ่น โดยไม่ปิดบังขอบเขตความสดใหม่ของข้อมูล

16 ก.ค. 2569 · อ่าน 7 นาที

goldprice.dev และ exchangerate.dev เป็นผลิตภัณฑ์พี่น้องที่ดำเนินการโดยบริษัทเดียวกัน ในระบบใช้งานจริง goldprice.dev เป็นผู้รับผิดชอบสัญญาราคาทองคำ ส่วน exchangerate.dev จัดหาส่วนของอัตราแลกเปลี่ยนสำหรับสกุลเงินลอยตัวที่รองรับ ขอบเขตนี้มีความสำคัญ: ราคาทองคำในสกุลท้องถิ่นประกอบด้วยค่าสังเกตตลาดสองจุด และความสดใหม่ของค่าหนึ่งไม่สามารถทำให้อีกค่าหนึ่งสดใหม่ตามไปด้วย

  • goldprice.dev เป็นผู้รับผิดชอบราคาทองคำและการตอบกลับการแปลงค่าแบบสาธารณะ ส่วน exchangerate.dev จัดหาส่วนของอัตราแลกเปลี่ยน
  • endpoint สาธารณะ /v1/convert ของ goldprice.dev คือเส้นทางใช้งานจริงแบบเรียกครั้งเดียว
  • นักพัฒนาสามารถเรียก API ทั้งสองแยกกันได้ เมื่อต้องการที่มาของข้อมูลที่ตรวจสอบย้อนกลับได้
  • จัดเก็บ computed_at ของทองคำ และ data_updated_at, timestamp, source, market_session ของอัตราแลกเปลี่ยนแยกจากกัน
  • ราคาที่แปลงค่าแล้วเป็นมูลค่าตลาดเชิงบ่งชี้ ไม่ใช่ราคาสำหรับการซื้อขายจริงจากผู้ค้าหรือราคาชำระบัญชี

ขอบเขตของระบบใช้งานจริง

goldprice.dev เริ่มต้นด้วยค่าสังเกตราคาโลหะในสกุลดอลลาร์สหรัฐ ส่วน exchangerate.dev ให้ค่าสังเกตอัตราแลกเปลี่ยนจากดอลลาร์สหรัฐไปยังสกุลเงินท้องถิ่นที่สอดคล้องกันสำหรับสกุลเงินลอยตัวที่รองรับ จากนั้น goldprice.dev จะเป็นผู้รับผิดชอบสัญญาการแปลงค่าเฉพาะโลหะ ซึ่งรวมถึงหน่วย สัญลักษณ์ที่รองรับ การตรวจสอบความถูกต้อง และการตอบกลับขั้นสุดท้าย

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

สูตรการแปลงค่า

ทองคำมักถูกเสนอราคาเป็นดอลลาร์สหรัฐต่อทรอยออนซ์ ขณะที่การแสดงผลในสกุลท้องถิ่นมักต้องการจำนวนเงินต่อกรัม ให้แปลงหน่วยน้ำหนักก่อน แล้วจึงคูณด้วยอัตราแลกเปลี่ยนดอลลาร์สหรัฐ:

formula · USD/oz to local currency/gram
const GRAMS_PER_TROY_OZ = 31.1035;function localGoldPerGram(usdPerTroyOz, usdToLocalRate) {  return (usdPerTroyOz / GRAMS_PER_TROY_OZ) * usdToLocalRate;}

ค่าคงที่ของหน่วยน้ำหนักนั้นตายตัว แต่ข้อมูลนำเข้าจากตลาดทั้งสองไม่ใช่: ทั้งราคาทองคำและอัตราแลกเปลี่ยนต่างมีเวลาสังเกตและกฎความสดใหม่เป็นของตัวเอง

เส้นทางใช้งานจริงแบบเรียกครั้งเดียว

สำหรับผู้เรียกใช้งาน ขอบเขตของระบบใช้งานจริงคือ goldprice.dev `/v1/convert` ซึ่งรวมส่วนของโลหะและอัตราแลกเปลี่ยนไว้เบื้องหลัง endpoint เดียวที่รู้จักโลหะ และไม่ต้องใช้ API key ตัวอย่างนี้ร้องขอมูลค่าของทองคำหนึ่งกรัมเป็นสกุลเงินรูเปียห์อินโดนีเซีย:

javascript · one-request conversion
const params = new URLSearchParams({  from: "XAU",  to: "IDR",  amount: "1",  unit: "gram",});const response = await fetch(  `https://api.goldprice.dev/v1/convert?${params}`,);if (!response.ok) {  throw new Error(`goldprice.dev returned ${response.status}`);}const conversion = await response.json();console.log(conversion.result, conversion.to, conversion.timestamp);

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

การผสานระบบแบบสองส่วนที่ตรวจสอบย้อนกลับได้

เรียก API ทั้งสองตัวเมื่อคุณต้องการเก็บ timestamp ของแต่ละแหล่งข้อมูล แคชค่านำเข้าแยกจากกัน หรืออธิบายได้ว่าส่วนใดที่ข้อมูลเก่าไป goldprice.dev spot จัดหาราคาทองคำดอลลาร์สหรัฐต่อทรอยออนซ์ ส่วน exchangerate.dev จัดหาอัตราแลกเปลี่ยนดอลลาร์สหรัฐไปยังสกุลเงินท้องถิ่น

javascript · explicit gold and FX legs
const GRAMS_PER_TROY_OZ = 31.1035;async function getGoldInCurrencies(currencies) {  const symbols = currencies.join(",");  const [spotResponse, fxResponse] = await Promise.all([    fetch("https://api.goldprice.dev/v1/spot/XAU-USD-SPOT"),    fetch(`https://api.exchangerate.dev/v1/latest/USD?symbols=${symbols}`),  ]);  if (!spotResponse.ok || !fxResponse.ok) {    throw new Error("A market-data request failed");  }  const spot = await spotResponse.json();  const fx = await fxResponse.json();  const usdPerGram = Number(spot.price) / GRAMS_PER_TROY_OZ;  return {    goldComputedAt: spot.computed_at,    fxDataUpdatedAt: fx.data_updated_at,    fxResponseTimestamp: fx.timestamp,    fxSource: fx.source,    fxMarketSession: fx.market_session,    prices: Object.fromEntries(      currencies.map((currency) => [        currency,        usdPerGram * Number(fx.rates[currency]),      ]),    ),  };}const result = await getGoldInCurrencies(["EUR", "IDR", "JPY"]);
timestamp ของการตอบกลับ ไม่ใช่ timestamp ของตลาด

เก็บรักษา spot.computed_at ไว้สำหรับค่าสังเกตราคาทองคำ และ fx.data_updated_at สำหรับค่าสังเกตอัตราแลกเปลี่ยนที่เก่าที่สุดที่มีส่วนร่วม ค่า timestamp ของอัตราแลกเปลี่ยนคือเวลาที่สร้างการตอบกลับ ส่วน source และ market_session เพิ่มบริบทของประเภทข้อมูลและช่วงเวลาซื้อขาย อย่าแทนที่ฟิลด์เหล่านี้ด้วย Date.now()

เหตุใดทั้งสองบริการจึงยังคงแยกจากกัน

การผสานระบบนี้ไม่ได้ทำให้ exchangerate.dev กลายเป็นเอนจินราคาทองคำทั้งหมด แต่ยังคงเป็นเพียงชั้นข้อมูลอัตราแลกเปลี่ยน การรักษาขอบเขตนี้ให้ชัดเจนช่วยป้องกันไม่ให้ความสดใหม่ของสกุลเงิน ความสดใหม่ของโลหะ และกฎการแปลงค่าเฉพาะผลิตภัณฑ์ ถูกรวมกันเป็นค่าเดียวที่กำกวม

  • goldprice.dev สามารถเปิดให้ใช้งานอินเทอร์เฟซขนาดเล็กเฉพาะโลหะ โดยไม่ต้องให้ผู้เรียกใช้งานประกอบเส้นทางทั่วไปด้วยตัวเอง
  • exchangerate.dev ยังคงรักษาสัญญาอัตราแลกเปลี่ยนทั่วไปที่มีประโยชน์นอกเหนือขอบเขตของโลหะ
  • ผู้ใช้งานที่ต้องการตรวจสอบย้อนกลับสามารถดึงและจัดเก็บค่าสังเกตทั้งสองแยกจากกันได้
  • แต่ละบริการสามารถรายงานความล้มเหลวและความสดใหม่ โดยใช้คำศัพท์เฉพาะของข้อมูลตลาดของตัวเอง

จัดการส่วนข้อมูลที่เก่าหรือขาดหายไปอย่างชัดเจน

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

  • ตรวจสอบการตอบกลับ HTTP ทั้งสองรายการก่อนทำการคำนวณ
  • ปฏิเสธราคาและอัตราที่ไม่ใช่จำนวนจำกัดหรือไม่เป็นบวก
  • กำหนดเกณฑ์ความสดใหม่แยกกันสำหรับทองคำและอัตราแลกเปลี่ยน
  • พิจารณา market_session: weekend เป็นเพียงบริบท ไม่ใช่หลักฐานว่าอัตราที่ยังคงค้างอยู่นั้นเป็นข้อมูลปัจจุบัน
  • บันทึกคู่สกุลเงินและเวลาสังเกตของข้อมูลต้นทางทั้งสองไว้พร้อมกับข้อผิดพลาดในการแปลงค่า

ปัดเศษเพื่อการแสดงผล ไม่ใช่ระหว่างการคำนวณ

รักษาความละเอียดเต็มรูปแบบตลอดการคูณ และปล่อยให้ locale ของการแสดงผลเป็นตัวกำหนดจำนวนตำแหน่งทศนิยมสุดท้าย Intl.NumberFormat จัดการสัญลักษณ์สกุลเงินและการจัดกลุ่มตัวเลขโดยไม่เปลี่ยนแปลงค่าที่แท้จริง:

javascript · locale-aware display
function formatPrice(amount, currency, locale) {  return new Intl.NumberFormat(locale, {    style: "currency",    currency,  }).format(amount);}console.log(formatPrice(result.prices.IDR, "IDR", "id-ID"));console.log(formatPrice(result.prices.JPY, "JPY", "ja-JP"));

ใช้ผลลัพธ์เป็นมูลค่าเชิงบ่งชี้

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

สิ่งที่กรณีศึกษานี้พิสูจน์

goldprice.dev คือหลักฐานจากฝ่ายแรกที่แสดงว่า exchangerate.dev สามารถจัดหาส่วนของอัตราแลกเปลี่ยนให้กับเวิร์กโฟลว์การตั้งราคาในระบบใช้งานจริงได้ นี่ไม่ใช่หลักฐานทางสังคมที่เป็นอิสระ หลักฐานที่มีประโยชน์จริงนั้นแคบกว่าและทำซ้ำได้: นักพัฒนาสามารถเรียกใช้ผลิตภัณฑ์สาธารณะชุดเดียวกัน เก็บรักษาเวลาสังเกตทั้งสองไว้ และตรวจสอบการคำนวณด้วยตัวเองได้

คำถาม

จะแปลงราคาทองคำจากดอลลาร์สหรัฐต่อออนซ์เป็นสกุลเงินท้องถิ่นต่อกรัมได้อย่างไร?

หารราคาดอลลาร์สหรัฐต่อทรอยออนซ์ด้วย 31.1035 แล้วคูณด้วยจำนวนหน่วยสกุลเงินท้องถิ่นต่อดอลลาร์สหรัฐ รักษาความละเอียดเต็มรูปแบบไว้จนถึงขั้นตอนการแสดงผลขั้นสุดท้าย

สามารถแปลงราคาทองคำเป็นสกุลเงินอื่นด้วยคำขอ API เพียงครั้งเดียวได้หรือไม่?

ได้ GET https://api.goldprice.dev/v1/convert รับค่า from=XAU สกุลเงินปลายทาง จำนวน และหน่วยโลหะ เช่น gram โดยจะคืนผลลัพธ์ที่แปลงค่าแล้ว และไม่จำเป็นต้องใช้ API key

เหตุใดจึงควรจัดเก็บ timestamp แยกกันสำหรับทองคำและอัตราแลกเปลี่ยนเงินตราต่างประเทศ?

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

ราคาทองคำในสกุลท้องถิ่นที่คำนวณได้เป็นราคาสำหรับการซื้อขายจริงจากผู้ค้าหรือไม่?

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

goldprice.dev เป็นลูกค้าอิสระของ exchangerate.dev หรือไม่?

ไม่ใช่ goldprice.dev และ exchangerate.dev เป็นผลิตภัณฑ์พี่น้องที่ดำเนินการโดยบริษัทเดียวกัน กรณีศึกษานี้บันทึกการผสานระบบใช้งานจริง ไม่ใช่คำรับรองจากบุคคลภายนอกที่เป็นอิสระ

อ่านต่อ

เริ่มต้นด้วยคีย์ API ฟรี

ส่งคำขอได้ 5,000 ครั้งต่อเดือนด้วยแพ็กเกจฟรี ไม่ต้องใช้บัตรเครดิต

รับคีย์ฟรี