Rust ช่วยให้คุณสร้าง HTTP เซิร์ฟเวอร์ที่รวดเร็วและปลอดภัยในไม่กี่ร้อยบรรทัด สิ่งที่ไม่ได้ให้มาคือวงจรการตอบกลับที่รวดเร็วสำหรับการทดสอบเซิร์ฟเวอร์นั้น วงจรการคอมไพล์ใช้เวลานาน, cargo test จะรันทุกอย่างใหม่เมื่อมีการเปลี่ยนแปลง trait เพียงครั้งเดียว และเฟรมเวิร์ก HTTP ส่วนใหญ่ของ Rust กำหนดให้คุณต้องเขียนการทดสอบการรวม (integration test) แยกต่างหากสำหรับแต่ละ endpoint ก่อนที่คุณจะเรียกใช้งานมันแม้เพียงครั้งเดียว หากคุณต้องการส่งมอบ API ไม่ใช่แค่ไบนารี คุณจำเป็นต้องมีเครื่องมือที่อยู่นอกเครื่องมือของ Rust และสามารถสื่อสารกับเซิร์ฟเวอร์ที่กำลังทำงานอยู่ได้
คู่มือนี้จะอธิบายขั้นตอนการทดสอบ Rust API ทั้งหมดภายใน Apidog: การเชื่อมต่อ Apidog กับเซิร์ฟเวอร์ Axum หรือ Actix ของคุณ, การสร้างคำขอ (requests) ไปยัง endpoints ของคุณ, การตรวจสอบ JSON ที่แปลงด้วย Serde, การจัดการการยืนยันตัวตนด้วย JWT, การจำลอง (mocking) endpoints เพื่อให้ฝั่ง frontend ทำงานต่อไปได้ในขณะที่คุณกำลังพัฒนา handler ให้เสร็จสมบูรณ์ และการรวมทั้งหมดนี้เข้าเป็นสถานการณ์ทดสอบ CI เมื่อจบคู่มือนี้ คุณจะมีโปรเจกต์ Apidog ที่นำกลับมาใช้ซ้ำได้ ซึ่งจะช่วยตรวจจับความคลาดเคลื่อนของสัญญา (contract drift) ก่อนที่คำสั่ง cargo build --release จะเสร็จสิ้น
หากคุณเคยใช้งาน Postman หรือ curl คุณจะได้รับคุณสมบัติ "ออกแบบก่อน" (design-first) ของ Apidog ฟรี: เช่น OpenAPI spec ที่สร้างจากคำขอที่คุณบันทึกไว้, mock URL ที่สามารถแชร์ได้ และสภาพแวดล้อมสำหรับทีม ข้ามเรื่อง การย้ายจาก Postman ไปอ่านแยกต่างหาก; โพสต์นี้จะเน้นที่ Rust
สรุปย่อ
- รันเซิร์ฟเวอร์ Rust ของคุณในเครื่อง (
cargo runกับโปรเจกต์ Axum หรือ Actix-web), เพิ่ม base URLhttp://localhost:3000เป็น Apidog environment และเก็บข้อมูลลับต่างๆ เป็นตัวแปร - สร้างคำขอแรกสำหรับ
GET /healthz, บันทึกไว้ และนำการยืนยันตัวตน (auth) กับ base URL ไปใช้ซ้ำกับทุก handler ในโฟลเดอร์ - สำหรับ JSON endpoints ให้วาง Serde struct ของคุณลงใน editor ของ Apidog สำหรับ body และยืนยันรูปแบบการตอบกลับด้วยสคริปต์ Tests ที่จะทำงานหลังจากการส่งทุกครั้ง
- สำหรับเส้นทางที่มีการป้องกัน (protected routes), สร้าง JWT เพียงครั้งเดียว, บันทึกเป็น
{{token}}และใช้ Bearer auth ที่ระดับโฟลเดอร์ เพื่อให้ทุกการทดสอบสืบทอดค่านี้ - จำลอง (Mock) Rust handlers ที่ยังไม่เสร็จใน Apidog เพื่อให้ทีม frontend ของคุณสามารถแสดงผลการตอบกลับจริงได้ก่อนที่ handler จะคอมไพล์ได้อย่างสมบูรณ์
- บันทึกชุดการทำงานเป็น Test Scenario, ส่งออก และรันใน CI ด้วย
apidog-cliทุก PR ที่เกี่ยวข้องกับ handler จะได้รับการตรวจสอบสัญญา (contract check) ก่อนการรวม (merge)
ทำไมต้องทดสอบ Rust API นอก Rust toolchain
cargo test นั้นดี แต่ก็ช้า ไม่โปร่งใสสำหรับเพื่อนร่วมทีมที่ไม่ได้ใช้ Rust และสร้างขึ้นโดยเน้นโค้ดมากกว่า HTTP หากคุณต้องการตรวจสอบว่า handler ของคุณส่งคืนสถานะโค้ดที่ถูกต้อง, รูปแบบ JSON ที่ถูกต้อง, ส่วนหัว (headers) ที่ถูกต้อง และข้อความแสดงข้อผิดพลาดที่ถูกต้องเมื่อข้อมูลที่ป้อนไม่ถูกต้อง คุณจะต้องเขียนการเรียกใช้ tower::ServiceExt::oneshot ใหม่สำหรับแต่ละกรณี จากนั้นคุณต้องดูแลรักษาสิ่งนั้นเมื่อ handler มีการเปลี่ยนแปลง และคุณต้องเขียนมันอีกครั้งใน JavaScript เพื่อให้ frontend สามารถเรียกใช้ mock ได้
Apidog มอบเลเยอร์สัญญา (contract layer) เดียวกันบนเซิร์ฟเวอร์ที่กำลังทำงานอยู่ คำขอมีอยู่เพียงครั้งเดียว การยืนยัน (Assertions) อยู่ถัดจากคำขอ เพื่อนร่วมทีม frontend เปิดโปรเจกต์เดียวกันและเห็นคำขอเดียวกับที่คุณเห็น เมื่อ Serde ได้รับแอตทริบิวต์ #[serde(rename_all = "camelCase")] ในอีกสามสัปดาห์ข้างหน้า การทดสอบที่จะล้มเหลวคือการทดสอบใน Apidog ไม่ใช่การทดสอบที่ส่งขึ้นโปรดักชัน
สามเหตุผลหลักในการเพิ่ม Apidog เข้าสู่ขั้นตอนการทำงานของ Rust:
- การตรวจสอบสัญญาแยกออกจากกระบวนการบิลด์. Apidog ทำงานกับไบนารีที่กำลังรันอยู่ คุณไม่จำเป็นต้องรอ
rustcเพื่อตรวจสอบว่า endpoint ของคุณยังคงส่งคืน200 - Mocks สามารถแชร์ได้. นักพัฒนา frontend ในเขตเวลาอื่นได้รับ URL ที่ส่งคืน JSON ที่ถูกต้อง ไม่ใช่ข้อความ Slack ที่บอกว่า “handler ยังไม่เสร็จ”
- OpenAPI ฟรี. Apidog สามารถสร้างเอกสาร OpenAPI 3.1 จากคำขอที่บันทึกไว้ คุณสามารถส่งมอบสิ่งนี้ให้กับใครก็ตามที่ต้องการ typed client โดยไม่ต้องเขียนคำอธิบายประกอบ
utoipaหรือaideบนทุกเส้นทาง
ขั้นตอนที่ 1: เพิ่ม Rust เซิร์ฟเวอร์ของคุณเป็น Apidog environment
เริ่มต้น Rust API ของคุณ สำหรับโปรเจกต์ Axum โค้ดพื้นฐานคือ:
use axum::{routing::get, Router};
use tokio::net::TcpListener;
#[tokio::main]
async fn main() {
let app = Router::new().route("/healthz", get(|| async { "ok" }));
let listener = TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
เปิด Apidog สร้างโปรเจกต์ใหม่ จากนั้นเปิด Environment Management (เมนูดร็อปดาวน์ด้านบนขวา) และเพิ่ม environment ชื่อ Rust Local:
| ตัวแปร | ค่า |
|---|---|
baseUrl |
http://localhost:3000 |
token |
เว้นว่างไว้ก่อน |
apiVersion |
v1 |
เพิ่ม environment ที่สองชื่อ Rust Staging พร้อมกับ base URL ที่ใช้งานจริง Apidog จะกำหนดขอบเขตตัวแปรต่อ environment ดังนั้นคุณสามารถสลับจาก local ไป staging ได้ด้วยการคลิกดรอปดาวน์เพียงครั้งเดียว ไม่ต้องค้นหาและแทนที่ผ่านคำขอที่บันทึกไว้
ขั้นตอนที่ 2: เรียกใช้งาน endpoint แรก
สร้างโฟลเดอร์ชื่อ Rust API ภายในโปรเจกต์ จากนั้นสร้างคำขอใหม่:
- Method:
GET - URL:
{{baseUrl}}/healthz
กด Send หากเซิร์ฟเวอร์ของคุณกำลังทำงานอยู่ คุณจะได้รับ 200 พร้อม body เป็น ok บันทึกสิ่งนี้เป็น health-check นี่คือ smoke test ที่ง่ายที่สุด และยืนยันว่า environment และ base URL ทำงานได้ก่อนที่คุณจะเขียนอะไรที่ซับซ้อนกว่านี้
หากคุณได้รับข้อผิดพลาด connection refused แสดงว่าเซิร์ฟเวอร์ของคุณไม่ได้ผูกกับ 0.0.0.0 หรือพอร์ตไม่ถูกต้อง TcpListener::bind("127.0.0.1:3000") ค่าเริ่มต้นของ Rust จะปฏิเสธคำขอที่มาจากสิ่งใดก็ตามที่ถูก resolve เป็น localhost บนอินเทอร์เฟซอื่น; ให้ผูกกับ 0.0.0.0 สำหรับการพัฒนาในเครื่อง เพื่อให้ Apidog และ Docker containers สามารถเข้าถึงได้
ขั้นตอนที่ 3: ทดสอบคำขอและคำตอบ JSON ด้วย Serde
รูปแบบ Rust API ที่พบบ่อยที่สุดคือ handler แบบ JSON-in, JSON-out ที่สนับสนุนโดย Serde struct เพิ่มเส้นทาง POST /users:
use axum::{extract::Json, routing::post, Router};
use serde::{Deserialize, Serialize};
#[derive(Deserialize)]
struct CreateUser {
name: String,
email: String,
}
#[derive(Serialize)]
struct User {
id: u64,
name: String,
email: String,
}
async fn create_user(Json(payload): Json<CreateUser>) -> Json<User> {
Json(User { id: 1, name: payload.name, email: payload.email })
}
let app = Router::new().route("/users", post(create_user));
ใน Apidog สร้างคำขอ:
- Method:
POST - URL:
{{baseUrl}}/users - Body (JSON):
{
"name": "Ada Lovelace",
"email": "ada@example.com"
}
ส่งคำขอ คุณจะได้รับ JSON ของ User กลับมา บันทึกเป็น create-user
ตอนนี้เปิดแท็บ Tests และเพิ่ม assertions:
pm.test("Status is 200", () => {
pm.expect(pm.response.code).to.eql(200);
});
pm.test("Body has id, name, email", () => {
const body = pm.response.json();
pm.expect(body).to.have.property("id");
pm.expect(body.name).to.eql("Ada Lovelace");
pm.expect(body.email).to.match(/^[^@]+@[^@]+$/);
});
ครั้งต่อไปที่มีคนเพิ่ม #[serde(rename_all = "camelCase")] ไปยัง struct และรูปแบบการตอบกลับของคุณเปลี่ยนจาก user_id เป็น userId การทดสอบนี้จะล้มเหลวก่อนที่จะมีการใช้งานการเปลี่ยนแปลง นั่นคือสัญญาที่ Apidog มอบให้คุณ ซึ่ง cargo test ไม่ได้ให้ เพราะ cargo test รันโค้ด Rust ของคุณกับ Rust types ของคุณ และจะผ่านได้ไม่ว่าจะเป็นรูปแบบใดก็ตาม
ขั้นตอนที่ 4: ครอบคลุมกรณีที่ Serde ปฏิเสธ (rejection cases)
ส่วนที่น่าสนใจของการจัดการ JSON ใน Rust คือสิ่งที่ Serde ทำกับอินพุตที่ไม่ถูกต้อง โดยค่าเริ่มต้น Axum จะส่งคืน 422 Unprocessable Entity โดยไม่มีรายละเอียด สร้างคำขอสามรายการที่ตั้งใจจะทำให้ schema เสียหาย:
| คำขอ | Body | คาดหวัง |
|---|---|---|
create-user-missing-email |
{ "name": "Ada" } |
422, body กล่าวถึง missing field email |
create-user-extra-field |
{ "name": "Ada", "email": "a@b.c", "admin": true } |
200 หากไม่มี #[serde(deny_unknown_fields)]; มิฉะนั้น 422 |
create-user-wrong-type |
{ "name": 1, "email": "a@b.c" } |
422, กล่าวถึง invalid type: integer |
ยืนยันสถานะโค้ดแต่ละรายการใน Tests นี่เป็นวิธีที่ประหยัดที่สุดในการจัดทำเอกสารนโยบายการตรวจสอบความถูกต้องที่แท้จริงของคุณ หากคุณเปิดใช้งาน deny_unknown_fields ในภายหลัง การทดสอบที่สองจะเปลี่ยนเป็นสีแดงและแจ้งให้คุณทราบว่า public contract มีการเปลี่ยนแปลง
ขั้นตอนที่ 5: ทดสอบเส้นทางที่ป้องกันด้วย JWT
Rust API ส่วนใหญ่ที่ใช้งานจริงจะซ่อน handler ไว้หลัง auth middleware axum-extra JWT extractor ของ Axum เป็นรูปแบบที่พบบ่อย:
use axum_extra::extract::cookie::PrivateCookieJar;
use jsonwebtoken::{decode, DecodingKey, Validation};
async fn me(jar: PrivateCookieJar) -> Result<Json<User>, StatusCode> {
let token = jar.get("token").ok_or(StatusCode::UNAUTHORIZED)?;
let claims = decode::<Claims>(token.value(), &DecodingKey::from_secret(b"secret"), &Validation::default())
.map_err(|_| StatusCode::UNAUTHORIZED)?;
Ok(Json(User { id: claims.claims.sub, name: "Ada".into(), email: "ada@example.com".into() }))
}
ใน Apidog คุณไม่จำเป็นต้องสร้าง JWT ด้วยมือทุกครั้งที่รันการทดสอบ สร้าง Pre-Request Script ในโฟลเดอร์:
const jwt = require("jsonwebtoken");
const token = jwt.sign(
{ sub: 1, exp: Math.floor(Date.now() / 1000) + 3600 },
"secret"
);
pm.environment.set("token", token);
เปิดการตั้งค่าโฟลเดอร์, ตั้งค่า Auth เป็น Bearer Token, ค่า {{token}} คำขอทุกรายการในโฟลเดอร์นี้จะลงนามและแสดง JWT ใหม่ ข้อผิดพลาดที่เกิดจากโทเค็นเก่าจะหายไปจากการทดสอบของคุณ สำหรับรายละเอียดเพิ่มเติมเกี่ยวกับการยืนยันตัวตน โปรดดู วิธีทดสอบการยืนยันตัวตนด้วย JWT ใน API
ขั้นตอนที่ 6: ทดสอบ streaming และ Server-Sent Events
เฟรมเวิร์กเว็บของ Rust มีการสตรีมมิ่งเป็นคุณสมบัติหลัก การตอบกลับ Sse ของ Axum จะห่อหุ้ม futures::Stream และปล่อยชิ้นส่วน text/event-stream รูปแบบของข้อมูลคือ data: { ... }\n\n ต่อเฟรม ซึ่งจะสิ้นสุดเมื่อการเชื่อมต่อปิดลง หรือมีเหตุการณ์ "done" ชัดเจน
คำขอที่ใช้สิ่งนี้ดูเหมือนคำขอ GET ทั่วไป แต่แผงการตอบกลับใน Apidog จะเปลี่ยนเป็นโหมดสตรีมมิ่งเมื่อ Content-Type เป็น text/event-stream คุณจะเห็นแต่ละเฟรมเมื่อมาถึง พร้อมกับ timestamp นี่คือมุมมองที่คุณต้องการเมื่อกำลังแก้ไขปัญหา backpressure หรือ flush ที่หายไป
สิ่งที่ต้องยืนยัน:
- chunk แรกมาถึงภายใน SLA ที่คุณกำหนด Apidog จะแสดง latency ต่อ chunk ในแผงสตรีมมิ่ง
- ชื่อเหตุการณ์เฉพาะถูกเรียกใช้ก่อนการปิดการเชื่อมต่อ (เช่น
event: done) - ระยะเวลาสตรีมทั้งหมดมีขอบเขต Handler ที่ลืมที่จะออกจาก
while let Some(event) = stream.next().awaitจะสตรีมไปตลอด; Apidog จะแสดงสิ่งนี้และคุณสามารถตั้งค่า hard timeout ในการตั้งค่าคำขอเพื่อให้การทดสอบล้มเหลวได้
หาก endpoint ของคุณใช้ WebSockets แทน SSE, Apidog มีประเภทคำขอ WebSocket แยกต่างหาก รูปแบบการทำงานเหมือนกัน: สร้างการเชื่อมต่อเพียงครั้งเดียว, บันทึกลำดับข้อความ, และยืนยันการตอบกลับ
ขั้นตอนที่ 7: จำลอง (Mock) Rust API สำหรับการพัฒนา frontend แบบคู่ขนาน
Frontend มักจะไม่ถูกบล็อกด้วยเวลาคอมไพล์ของ Rust แต่จะถูกบล็อกด้วย handler ที่ยังไม่มีอยู่ Apidog mocks ช่วยให้คุณเผยแพร่ URL ที่เสถียร ซึ่งส่งคืนสัญญาที่คุณและ frontend ตกลงกันไว้ ก่อนที่ handler จะถูกนำไปใช้งานจริง
คลิกขวาที่ create-user, เลือก Smart Mock, และเปิดใช้งาน Apidog จะส่งคืนการตอบกลับ User แบบสังเคราะห์ที่ https://mock.apidog.com/m1/<projectId>/users Mock body จะตรงกับตัวอย่างที่คุณบันทึกไว้ Mock URL ยอมรับรูปแบบ body เดียวกัน ดังนั้น frontend สามารถ POST ไปยังมันได้ราวกับว่าเป็น Rust เซิร์ฟเวอร์จริง
สำหรับการจำลองแบบไดนามิก (dynamic mocks) ให้เปลี่ยนไปที่ Advanced Mock และเขียนสคริปต์:
return {
id: Math.floor(Math.random() * 10000),
name: body.name,
email: body.email,
createdAt: new Date().toISOString()
};
Mock นั้นจะตอบสนองต่อสิ่งที่ frontend ส่งมา โดยมี id และ timestamp ที่สร้างขึ้น เมื่อ Rust handler พร้อมใช้งาน frontend จะเปลี่ยน base URL กลับไปที่ http://localhost:3000 และไม่มีอะไรเปลี่ยนแปลง สำหรับข้อมูลเพิ่มเติมเกี่ยวกับรูปแบบนี้ ทีมงานยังได้กล่าวถึง การสร้างและทดสอบ Spring Boot API และ ขั้นตอนการทดสอบ API ทั่วไป; เป็นแนวคิดเดียวกัน แต่ใช้รันไทม์ต่างกัน
ขั้นตอนที่ 8: บันทึกเป็น CI test scenario
Apidog Test Scenarios จะเชื่อมโยงคำขอต่างๆ ด้วยตัวแปรที่ใช้ร่วมกัน และรันแบบ headless สร้าง scenario:
health-check, ยืนยัน200create-user, ยืนยัน200, เก็บbody.idเข้าสู่ตัวแปรcreate-user-missing-email, ยืนยัน422me(พร้อมกับ JWT pre-request), ยืนยัน200และidที่ส่งคืนตรงกับidที่เก็บไว้- คำขอ SSE, ยืนยันว่า stream เสร็จสมบูรณ์ภายใน 5 วินาที
ส่งออก scenario เป็น JSON, คอมมิตเข้าสู่ repo ของคุณภายใต้ tests/apidog/, และเรียกใช้จาก CI:
- name: Run API contract tests
run: |
cargo build --release
./target/release/myserver &
sleep 2
apidog-cli run tests/apidog/contract.json --env "Rust Local"
ทุก PR ที่เกี่ยวข้องกับ handler จะถูกรันกับ Rust binary ที่ใช้งานจริง พร้อมกับชุด contract เต็มรูปแบบ หากการเปลี่ยนชื่อ Serde, การเปลี่ยนแปลงสถานะโค้ด, หรือการปรับแต่งการตรวจสอบ JWT ทำให้ public shape เสียหาย CI จะตรวจจับได้ก่อนที่ปุ่ม merge จะเปลี่ยนเป็นสีเขียว
ขั้นตอนที่ 9: สร้าง OpenAPI จากคำขอที่บันทึกไว้
เมื่อชุดคำขอมีความเสถียรแล้ว ให้เปิดเมนู Export ของ Apidog และเลือก OpenAPI 3.1 คุณจะได้เอกสาร spec ที่ครอบคลุมทุกคำขอที่บันทึกไว้ พร้อมตัวอย่าง body ที่คุณส่งไป มอบสิ่งนี้ให้กับใครก็ตามที่กำลังสร้าง typed client (TypeScript, Swift, Kotlin, Python) แล้วพวกเขาจะได้ contract ที่ตรงกับสิ่งที่ Rust เซิร์ฟเวอร์ของคุณส่งคืนในวันนี้ ไม่ใช่สิ่งที่ใครบางคนเขียนด้วยมือในไฟล์ .yaml เมื่อหกเดือนที่แล้ว
หากคุณต้องการให้ spec ถูกตรวจสอบเข้าสู่ Rust repo ของคุณ ให้รัน apidog-cli export จาก CI และเขียนลงใน openapi.json การ cargo build ครั้งต่อไปจะไม่เปลี่ยนแปลง แต่ผู้ใช้งาน API ทุกคนจะได้รับข้อมูลที่ถูกต้องบนดิสก์
คำถามที่พบบ่อย
- Apidog ใช้งานได้ทั้งกับ Axum และ Actix-web หรือไม่? ได้ Apidog สื่อสารด้วย HTTP ไม่ใช่ Rust สิ่งใดก็ตามที่ตอบสนองต่อคำขอได้ (Axum, Actix-web, Rocket, Warp, Poem, Loco) จะทำงานในลักษณะเดียวกัน ข้อพิจารณาเฉพาะของ Rust เพียงอย่างเดียวคือการผูกกับ
0.0.0.0แทนที่จะเป็น127.0.0.1สำหรับการทดสอบในเครื่อง - ฉันจะทดสอบ handlers ที่ panic ได้อย่างไร? รันเซิร์ฟเวอร์ของคุณด้วย
CatchPanicLayerของtower-httpที่อยู่หน้าเราเตอร์ การ panic จะเปลี่ยนเป็น500พร้อมกับ JSON body สร้างคำขอ Apidog ที่กระตุ้นเส้นทาง panic และยืนยัน500หากคุณไม่ห่อหุ้ม panic การเชื่อมต่อจะหลุดและ Apidog จะรายงานข้อผิดพลาดเครือข่าย ซึ่งก็เป็นการทดสอบสัญญาที่ถูกต้องเช่นกัน - ฉันสามารถรัน Apidog กับ Rust binary ใน Docker ได้หรือไม่? ได้ ชี้
baseUrlไปยังพอร์ตที่เปิดเผยของคอนเทนเนอร์และคุณก็เรียบร้อย หากคอนเทนเนอร์ทำงานอยู่ภายใน Docker Compose ให้ผู้รัน Apidog ของคุณอยู่ในเครือข่ายเดียวกัน หรือใช้พอร์ตที่แมปของโฮสต์ - แล้ว gRPC ล่ะ? Apidog มีประเภทคำขอ gRPC นำเข้าไฟล์
.protoของคุณ, เลือกบริการและเมธอด, กรอก request payload และส่ง รูปแบบการยืนยันตัวตน, environments และ test scenarios จะเหมือนกับ REST - Test scenario จะมาแทนที่
cargo testหรือไม่? ไม่ใช่ Unit tests สำหรับโค้ด Rust ของคุณยังคงอยู่ใน Rust Apidog จะทดสอบพื้นผิวที่ทำงานอยู่: HTTP contract ทั้งสองระดับจะตรวจจับข้อบกพร่องที่แตกต่างกัน Unit test ตรวจจับฟังก์ชันที่เสีย; Apidog test ตรวจจับรูปแบบการตอบกลับที่เสีย, CORS header ที่หายไป หรือ400ที่กลายเป็น422คุณต้องการทั้งสองอย่าง - Apidog ฟรีสำหรับโปรเจกต์ Rust open-source หรือไม่? ได้ ลูกค้า Apidog ฟรีสำหรับบุคคลและทีมขนาดเล็ก Test scenarios, mocks และ OpenAPI export เป็นส่วนหนึ่งของ free tier หากคุณดูแล Rust API สาธารณะ คุณสามารถส่งไฟล์โปรเจกต์ใน repo ของคุณเพื่อให้ใครก็ตามที่โคลนไปได้รับชุดทดสอบ
สรุป
Rust API สมควรได้รับวงจรตอบกลับที่ไม่ต้องรอคอมไพเลอร์ ชุดคำขอใน Apidog มอบวงจรนั้นให้คุณ: HTTP จริง, การยืนยันจริง, mocks จริงสำหรับ frontend และ CI scenario ที่รันกับไบนารีที่ทำงานอยู่ สร้างคำขอข้างต้นเพียงครั้งเดียว และการเปลี่ยนแปลงใดๆ ในอนาคตของ Axum หรือ Actix handler ของคุณจะกลายเป็นการทดสอบที่ควบคุมได้ แทนที่จะเป็นความประหลาดใจระหว่างรันไทม์
ดาวน์โหลด Apidog และเชื่อมต่อไปยัง Rust เซิร์ฟเวอร์ของคุณ การตั้งค่าใช้เวลาน้อยกว่าสิบนาที ผลลัพธ์ที่ได้คือสัญญาที่คุณควบคุมได้ แยกออกจาก cargo และทีม frontend ที่ไม่ต้องถามอีกต่อไปว่า handler เสร็จเมื่อไหร่
