เอนด์พอยต์ HTTPS ในฐานะเว็บฮุกน้ำหนักเบา
ผู้เรียนจะเปิดเผย Atlas Function เป็นเอนด์พอยต์ HTTPS และกำหนดค่าการตรวจสอบคำขอเพื่อใช้เป็นตัวรับเว็บฮุก
เอนด์พอยต์ HTTPS ในฐานะเว็บฮุกน้ำหนักเบา เป็นบทเรียน MongoDB Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน MongoDB Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส MongoDB Academy มีบทเรียนทั้งหมด 4 บทเรียน
บางส่วนของบทเรียนนี้ยังไม่ได้รับการแปล และแสดงเป็นภาษาอังกฤษ
What Are Atlas HTTPS Endpoints?
Atlas HTTPS Endpoints (formerly Webhooks) expose an Atlas Function as a publicly accessible URL that accepts HTTP requests. They let external services (GitHub, Stripe, Twilio, Shopify, custom CI/CD pipelines) call your Atlas Function by posting to a URL — turning your database into a lightweight API backend with no separate server required.
Creating an HTTPS Endpoint
In Atlas App Services, go to HTTPS Endpoints and click Add an Endpoint. Configure: Route (URL path, e.g., /api/orders), HTTP Method (GET, POST, PUT, DELETE, or ANY), Authentication (application auth, user auth, or no auth for public endpoints), and the Linked Function that handles the request. The generated URL looks like: https://data.mongodb-api.com/app/APP_ID/endpoint/api/orders.
// The HTTPS endpoint URL format:
// https://data.mongodb-api.com/app/{APP_ID}/endpoint{route}
// Example endpoint configuration:
// Route: /webhook/stripe
// HTTP Method: POST
// Auth: no auth (Stripe handles its own signature)
// Function: handleStripeWebhookThe Request Object
The linked function receives a single argument — the request object — which contains all HTTP request data: body (raw body or parsed JSON), headers (a map of header name to array of values), query (URL query parameters), httpMethod, and rawUrl. Parse the body with EJSON.parse(body.text()) for JSON payloads.
exports = async function(request) {
// Access headers, query params, and body
const contentType = request.headers['Content-Type']
const page = parseInt(request.query.page) || 1
const bodyText = request.body.text()
const payload = EJSON.parse(bodyText)
console.log('Received ' + request.httpMethod + ' with page=' + page)
console.log('Body:', JSON.stringify(payload))
}Returning a Response
The function's return value becomes the HTTP response. Return a plain object to send it as JSON (Atlas automatically serialises it with a 200 status). To control the status code and headers explicitly, use Atlas's Response object or return a specific shape. Always return a response — an undefined return becomes an empty 200.
exports = async function(request) {
// Simple JSON response (200 OK)
return { success: true, data: [1, 2, 3] }
// Custom status code and headers
// return {
// statusCode: 201,
// headers: { 'X-Request-Id': ['abc123'] },
// body: JSON.stringify({ id: newDoc._id })
// }
// Error response
// return {
// statusCode: 400,
// body: JSON.stringify({ error: 'Missing required field: email' })
// }
}Webhook Signature Validation
When acting as a webhook receiver for services like Stripe, GitHub, or Twilio, always validate the request signature before processing it. Each service sends a header (e.g., Stripe-Signature, X-Hub-Signature-256) that contains an HMAC of the request body signed with your webhook secret. Verify it before touching the database.
exports = async function(request) {
// Validate Stripe webhook signature
const sigHeader = request.headers['Stripe-Signature'][0]
const bodyText = request.body.text()
const webhookSecret = context.values.get('STRIPE_WEBHOOK_SECRET')
// Compute expected signature (simplified — use a library in real code)
const crypto = require('crypto')
const timestamp = sigHeader.split(',').find(p => p.startsWith('t=')).split('=')[1]
const expectedSig = crypto
.createHmac('sha256', webhookSecret)
.update(timestamp + '.' + bodyText)
.digest('hex')
const receivedSig = sigHeader.split(',').find(p => p.startsWith('v1=')).split('=')[1]
if (receivedSig !== expectedSig) {
return { statusCode: 401, body: JSON.stringify({ error: 'Invalid signature' }) }
}
// Safe to process
const event = EJSON.parse(bodyText)
// ...
}Authentication Options
HTTPS endpoints support several authentication modes: No Auth — public endpoint, anyone with the URL can call it (use signature validation). Application Auth — caller must provide an App Services API key or JWT token. User Auth — caller must be an authenticated App Services user, and context.user is populated. Choose based on the caller: external webhooks usually use No Auth + signature validation; internal services use API keys.
// Calling a user-authenticated endpoint from a client app
const response = await fetch(
'https://data.mongodb-api.com/app/APP_ID/endpoint/api/profile',
{
method: 'GET',
headers: {
'Authorization': 'Bearer ' + userJwtToken,
'Content-Type': 'application/json'
}
}
)
const data = await response.json()Building a Lightweight REST API
You can use HTTPS endpoints to build a lightweight REST API backed by MongoDB without any Node.js server. Each route gets its own endpoint (or you use a single ANY-method endpoint and parse the path/method in the function). This is suitable for low-traffic microservices, prototypes, and internal tools where the overhead of a full application server is not justified.
// Single ANY-method endpoint handles multiple routes
exports = async function(request) {
const db = context.services.get('mongodb-atlas').db('mydb')
const path = request.rawUrl.split('/endpoint')[1] // e.g., '/api/orders'
if (request.httpMethod === 'GET' && path === '/api/orders') {
const orders = await db.collection('orders').find({}).limit(20).toArray()
return { statusCode: 200, body: EJSON.stringify(orders) }
}
if (request.httpMethod === 'POST' && path === '/api/orders') {
const body = EJSON.parse(request.body.text())
const result = await db.collection('orders').insertOne(body)
return { statusCode: 201, body: JSON.stringify({ id: result.insertedId }) }
}
return { statusCode: 404, body: JSON.stringify({ error: 'Not found' }) }
}Idempotency for Webhook Receivers
External services often retry webhook deliveries if your endpoint returns an error or times out. This means your endpoint function may be called multiple times with the same event. Design it to be idempotent: use the event's unique ID as a deduplication key. Check if the event was already processed before doing work, and use upserts rather than inserts.
exports = async function(request) {
const event = EJSON.parse(request.body.text())
const db = context.services.get('mongodb-atlas').db('mydb')
// Idempotency check: has this event been processed?
const existing = await db.collection('processed_events').findOne({ _id: event.id })
if (existing) {
return { statusCode: 200, body: JSON.stringify({ status: 'already_processed' }) }
}
// Process the event
await handleEvent(db, event)
// Mark as processed (atomic upsert)
await db.collection('processed_events').updateOne(
{ _id: event.id },
{ $set: { processedAt: new Date(), type: event.type } },
{ upsert: true }
)
return { statusCode: 200, body: JSON.stringify({ status: 'ok' }) }
}CORS and Browser Access
If you call an HTTPS endpoint from a browser (SPA or mobile web app), you need to configure CORS headers. In the endpoint settings, enable CORS and specify allowed origins. Atlas will add the appropriate Access-Control-Allow-Origin headers to responses and handle OPTIONS preflight requests automatically.
// Manual CORS headers if you need custom control
exports = async function(request) {
const corsHeaders = {
'Access-Control-Allow-Origin': ['https://myapp.com'],
'Access-Control-Allow-Methods': ['GET, POST, OPTIONS'],
'Access-Control-Allow-Headers': ['Content-Type, Authorization']
}
// Handle preflight
if (request.httpMethod === 'OPTIONS') {
return { statusCode: 204, headers: corsHeaders, body: '' }
}
// Handle actual request
const data = await getData()
return { statusCode: 200, headers: corsHeaders,
body: JSON.stringify(data) }
}Rate Limiting and Abuse Prevention
Public HTTPS endpoints can be abused. Atlas has built-in rate limits (requests per second per endpoint), but for additional protection: validate request signatures for webhooks, add IP-based rate limiting by recording request counts per IP in MongoDB with a TTL index, and keep endpoint functions lightweight by offloading heavy processing to a database trigger or queue.
// Simple IP-based rate limiting
exports = async function(request) {
const ip = request.headers['X-Forwarded-For'][0]
const db = context.services.get('mongodb-atlas').db('mydb')
const windowMs = 60 * 1000 // 1 minute
const maxRequests = 30
const now = Date.now()
const record = await db.collection('rate_limits').findOneAndUpdate(
{ _id: ip, resetAt: { $gt: new Date(now) } },
{ $inc: { count: 1 }, $setOnInsert: { resetAt: new Date(now + windowMs) } },
{ upsert: true, returnDocument: 'after' }
)
if (record && record.count > maxRequests) {
return { statusCode: 429, body: JSON.stringify({ error: 'Rate limit exceeded' }) }
}
// Proceed...
}Logging and Debugging Endpoints
Use console.log() in your endpoint function for debugging — all output appears in the App Services execution log with a timestamp and invocation ID. For production, log the HTTP method, route, response status, and duration. Avoid logging sensitive data (API keys, passwords, full request bodies with PII). The execution log retains entries for 30 days in Atlas.
exports = async function(request) {
const start = Date.now()
const route = request.httpMethod + ' ' + request.rawUrl.split('/endpoint')[1]
try {
const result = await handleRequest(request)
console.log(JSON.stringify({ route, status: result.statusCode || 200, ms: Date.now() - start }))
return result
} catch (err) {
console.error(JSON.stringify({ route, status: 500, error: err.message, ms: Date.now() - start }))
return { statusCode: 500, body: JSON.stringify({ error: 'Internal server error' }) }
}
}Quick Check
Test your understanding of MongoDB & NoSQL Databases concepts from this lesson.
Lesson Recap
In this lesson you learned: Atlas HTTPS Endpoints expose an Atlas Function as a public URL for receiving webhooks and building lightweight APIs, always validate webhook signatures using the service's HMAC header before processing the payload, and idempotency with a processed-events deduplication collection prevents duplicate side effects from retried webhook deliveries. Next up: Time Series Collections in MongoDB 5.0+.
เรียนรู้ JavaScript ด้วย AI tutor — ฟรี
เขียนและเรียกใช้โค้ดจริงในเบราว์เซอร์ของคุณ รับความช่วยเหลือทันทีจาก AI tutor 24/7 และเรียนรู้ต่อจากที่คุณหยุดบนเว็บหรือในแอป
- คอร์ส
- 30
- บทเรียน
- 120
คำถามที่พบบ่อย
บทเรียน “เอนด์พอยต์ HTTPS ในฐานะเว็บฮุกน้ำหนักเบา” ฟรีหรือไม่
ใช่ — ข้อความเต็มของ “เอนด์พอยต์ HTTPS ในฐานะเว็บฮุกน้ำหนักเบา” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส MongoDB Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส MongoDB Academy มีบทเรียนทั้งหมด 4 บทเรียน
คุณจะเรียนรู้อะไรในบทเรียน “เอนด์พอยต์ HTTPS ในฐานะเว็บฮุกน้ำหนักเบา”
ผู้เรียนจะเปิดเผย Atlas Function เป็นเอนด์พอยต์ HTTPS และกำหนดค่าการตรวจสอบคำขอเพื่อใช้เป็นตัวรับเว็บฮุก คุณปฏิบัติ MongoDB Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน
คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน MongoDB Academy หรือไม่
ไม่จำเป็นต้องมีประสบการณ์มาก่อน MongoDB Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 4 จากทั้งหมด 4 บทเรียน
บทเรียน “เอนด์พอยต์ HTTPS ในฐานะเว็บฮุกน้ำหนักเบา” ใช้เวลานานแค่ไหน
บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย
ฉันเขียนและรันโค้ดในบทเรียน MongoDB Academy นี้ได้ไหม
ได้ บทเรียน MongoDB Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ
บทเรียนทั้งหมดในหลักสูตรนี้
- ทริกเกอร์ฐานข้อมูล: การตอบสนองต่อเหตุการณ์ CRUD
- ทริกเกอร์ตามกำหนดเวลาและงาน Cron
- การเขียน Atlas Functions ด้วย JavaScript
- เอนด์พอยต์ HTTPS ในฐานะเว็บฮุกน้ำหนักเบา