API reference @cogover/sdk: Outbound HTTP và secret
Trang này thuộc API reference của @cogover/sdk.
Outbound HTTP fetch
function fetch(input: string, init?: CogoverFetchInit): Promise<CogoverFetchResponse>;
interface CogoverFetchInit {
readonly method?: "GET" | "HEAD" | "POST" | "PUT" | "PATCH" | "DELETE";
readonly headers?: Readonly<Record<string, string>>;
readonly body?: string;
readonly timeoutMs?: number;
readonly credential?: string;
}
interface CogoverFetchHeaders {
get(name: string): string | null;
has(name: string): boolean;
entries(): IterableIterator<[string, string]>;
[Symbol.iterator](): IterableIterator<[string, string]>;
}
interface CogoverFetchResponse {
readonly ok: boolean;
readonly status: number;
readonly statusText: string;
readonly url: string;
readonly redirected: false;
readonly headers: CogoverFetchHeaders;
readonly bodyUsed: boolean;
text(): Promise<string>;
json<T = unknown>(): Promise<T>;
}
Cogover cài đặt global fetch() trong hosted runtime. Import { fetch } từ
@cogover/sdk khi muốn khai báo dependency tường minh; cách này cũng ngăn Node.js
trên máy local âm thầm dùng native fetch không bị giới hạn khi chạy test. Hàm
fetch của SDK yêu cầu Cogover runtime và luôn dùng lớp network do Cogover quản
lý. input phải là URL HTTPS public tuyệt đối, không chứa userinfo, fragment hoặc
IP literal, trên port 443 hoặc trên origin đã được duyệt cho project (xem
Port khác). body chỉ nhận string; dùng JSON.stringify() cho JSON.
timeoutMs phải là số nguyên dương và luôn bị giới hạn bởi hạn mức của platform.
Giá trị này không kéo dài lần thực thi: HTTP route mặc định có tổng cộng 8 giây, nên ở
đó server chậm hơn sẽ kết thúc toàn bộ lần thực thi (xem
Giới hạn của một lần thực thi).
import { fetch } from "@cogover/sdk";
const response = await fetch("https://api.example.com/v1/orders", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ id: "ORD-1" }),
timeoutMs: 5_000,
});
CogoverFetchResponse có ok, status, statusText, url, redirected (luôn
false), headers, bodyUsed, text() và json<T>(). Body được buffer có giới
hạn và chỉ được đọc một lần. headers.get(name), has(name), entries() và iterator
không phân biệt hoa/thường.
V1 không tự follow redirect, không lưu/gửi cookie, không streaming request/response,
không WebSocket và không nhận signal, credentials, redirect, proxy, dispatcher,
agent, DNS resolver hay TLS configuration. Không hỗ trợ URL HTTP, port khác 443 mà
project chưa được duyệt, userinfo hoặc IP-literal host. Header framing/hop-by-hop/proxy/forwarding và header
request dành riêng cho Cogover bị từ chối. Request/response, header, thời gian, số call, destination
và concurrency đều có quota.
- Request
GEThoặcHEADcóbodythất bại vớiFETCH_BLOCKED. - Response nén, tức có
Content-Encodingkhácidentity, thất bại vớiFETCH_BLOCKED. - Body của response được giải mã theo UTF-8: byte không hợp lệ theo UTF-8 thành U+FFFD, nên không đọc chính xác được nội dung nhị phân.
- Host name phân giải ra địa chỉ không phải public thất bại với
FETCH_FAILED. - Các lời gọi bắt đầu cùng lúc, ví dụ bằng
Promise.all, được gửi lần lượt từng lời gọi. -
Trigger before-change không được gọi
fetch: lời gọi némPermissionDeniedErrorcódetails.reasonlà"TRIGGER_READ_ONLY". Preview version chế độ chỉ đọc chỉ cho phépGETvàHEADkhông cócredential, các lời gọi khác bị từ chối bằngPermissionDeniedError.
Lỗi được ném dưới dạng CogoverApiError với code FETCH_DISABLED, FETCH_BLOCKED,
FETCH_REQUEST_TOO_LARGE, FETCH_RESPONSE_TOO_LARGE, FETCH_TIMEOUT hoặc
FETCH_FAILED; quota dùng RateLimitError. Một lần thực thi gọi fetch tối đa 20 lần,
và mỗi lần cũng tính vào ngân sách capability call của lần thực thi (xem
Giới hạn của một lần thực thi); vượt một
trong hai đều được báo bằng RateLimitError. Với POST/PUT/PATCH/DELETE bị timeout
hoặc mất response, remote server có thể đã xử lý request. Hãy dùng idempotency key
của API đích và không retry mù.
Port khác
Hệ thống chỉ công bố trên port khác, ví dụ https://erp.example.com:9899, gọi được
sau khi quản trị viên Workspace duyệt đúng origin đó trong mục fetch của identity
policy của project. Việc duyệt chỉ áp dụng cho các origin https://host:port được
liệt kê; port khác của cùng host vẫn bị chặn. Mọi quy tắc khác trong mục này vẫn áp
dụng cho origin đã duyệt: HTTPS với chứng chỉ hợp lệ cho host, chỉ địa chỉ public,
không follow redirect và cùng các giới hạn. URL trên port chưa được duyệt thất bại với
FETCH_BLOCKED. Request rời Cogover từ các địa chỉ outbound dùng chung với Workspace
khác, nên whitelist các địa chỉ đó trên firewall không xác định được Workspace của bạn:
hệ thống đích cần xác thực request, ví dụ bằng credential.
// Chỉ gọi được sau khi "https://erp.example.com:9899" được duyệt cho project này.
const orders = await fetch("https://erp.example.com:9899/api/orders?status=new");Xác thực bằng credential
credential là tên một credential mà quản trị viên đã lưu cho project (xem
Secret và credential). Cogover thêm header xác thực của
credential vào request, nên code của project không bao giờ chạm tới giá trị:
const response = await fetch("https://erp.example.com/v1/orders", {
method: "POST",
credential: "erp_api",
headers: { "content-type": "application/json" },
body: JSON.stringify({ id: "ORD-1" }),
});
Tuỳ cách credential được tạo, Cogover gửi Authorization: Bearer <value>,
Authorization: Basic <base64 của value> hoặc một header với tên đã cấu hình. Tên
phải bắt đầu bằng chữ cái và chứa tối đa 64 chữ cái, chữ số hoặc dấu gạch dưới.
Credential chỉ được gửi tới các host mà quản trị viên cho phép. Host ghi không kèm
port chỉ cho phép port 443; để dùng credential với origin đã duyệt trên port khác,
quản trị viên ghi host:port, ví dụ erp.example.com:9899. Request tới host hoặc
port khác, request tự đặt cùng header, hoặc tên không phải credential đang active sẽ
thất bại với FETCH_BLOCKED. Redirect không bao giờ được follow, nên credential
không bao giờ rời khỏi host được phép.
Secret và credential
Quản trị viên lưu secret cho project qua management API của Cogover. Mỗi secret
hoặc là secret có giá trị được code đọc bằng secrets.get, hoặc là
credential chỉ dùng cho fetch (xem
Xác thực bằng credential); giá trị của credential
không bao giờ đọc được từ code. Giá trị được lưu mã hoá và không bao giờ được
management API trả về, ghi log hay đưa vào thông báo lỗi.
interface SecretsApi {
get(name: string): Promise<string>;
}const token = await secrets.get("erp_token");
const response = await fetch("https://erp.example.com/v1/orders", {
headers: { authorization: `Bearer ${token}` },
});secrets.get(name): Promise<string>
Trả về giá trị hiện tại của secret. name bắt đầu bằng chữ cái và chứa tối đa 64
chữ cái, chữ số hoặc dấu gạch dưới; tên khác ném ValidationError trước khi gọi.
Secret không tồn tại hoặc đã bị disable ném ValidationError với thông báo
Secret '<name>' is not available, còn credential ném ValidationError với
Secret '<name>' is a credential and cannot be read.
secrets.get hoạt động trong script và route, trigger after-change, job và lời gọi
inbound webhook. Trigger before-change bị từ chối bằng PermissionDeniedError
(details.reason === "TRIGGER_READ_ONLY"); phiên phát triển local chỉ đọc được
secret khi quản trị viên cho phép, nếu không reason là "SECRETS_NOT_ALLOWED".
Một invocation đọc secret tối đa 20 lần; mọi lần đọc đều được tính, kể cả đọc lại cùng
tên và thao tác crypto dùng key { secret: name }, và lần thứ 21 ném RateLimitError.
secrets.get cũng tính là một capability call, còn thao tác crypto tính là một lời gọi
cục bộ (xem Giới hạn của một lần thực thi). Khi secret chưa được bật cho Workspace, lỗi là CogoverApiError
với code: "SECRETS_DISABLED". Không bao giờ ghi giá trị secret vào log, record,
state hay response. Để ký, mã hoá hoặc giải mã bằng secret mà không đọc giá trị,
truyền { secret: name } làm key của một thao tác crypto.
Rate this page
On this page