Http_Response简介
我们传统的访问canister的方法是通过agent代理访问,需要在支持JavaScript的环境中正常运行。但其实canister还支持Http Request访问,只需要一个URL就可返回相应的数据。
由于边缘节点与canister之间单次请求有cycleLimit,所以小型数据可通过无callback的http_response方法直接返回,而大型数据需要分片后,通过含callback的http_response方法串行返回。
例如,我们可以通过https://${canisterId}.raw.ic0.app/fileA这个URL向canister发出/fileA的请求信息,canister可根据业务逻辑进行自定义数据返回。
核心代码(Types + http_request函数)
type HeaderField = (Text, Text);
type StreamingCallbackHttpResponse = {
body: Blob;
token: ?Token;
};
type Token = {}; // 对象类型,可根据需要添加参数
type StreamingStrategy = {
#Callback: {
callback: shared (Token) -> async (StreamingCallbackHttpResponse);
token: Token;
}
};
type HttpRequest = {
method: Text;
url: Text;
headers: [HeaderField];
body: Blob;
};
type HttpResponse = {
status_code: Nat16;
headers: [HeaderField];
body: Blob;
streaming_strategy: ?StreamingStrategy;
};
public query func http_request(request: HttpRequest): async HttpResponse{
...
};
示例-无回调(Callback)函数型
import Text "mo:base/Text";
// 仅解析url,无callback版本
actor http {
type HeaderField = (Text, Text);
type StreamingCallbackHttpResponse = {
body: Blob;
token: ?Token;
};
type Token = {};
type StreamingStrategy = {
#Callback: {
callback: shared (Token) -> async (StreamingCallbackHttpResponse);
token: Token;
}
};
type HttpRequest = {
method: Text;
url: Text; // 为ic0.app后的路径
headers: [HeaderField];
body: Blob;
};
type HttpResponse = {
status_code: Nat16;
headers: [HeaderField];
body: Blob;
streaming_strategy: ?StreamingStrategy;
};
public query func http_request(request: HttpRequest): async HttpResponse {
if(request.url == "/fileA") {
{
status_code = 200;
headers = [];
body = Text.encodeUtf8("I'm file A.");
streaming_strategy = null;
}
} else {
{
status_code = 404;
headers = [];
body = Text.encodeUtf8("worng url");
streaming_strategy = null;
}
}
};
};
示例-回调(Callback)函数型
import Text "mo:base/Text";
import Blob "mo:base/Blob";
// callback版本
actor http {
let ans: [Text] = ["A","B","C","D","E"];
type HeaderField = (Text, Text);
type StreamingCallbackHttpResponse = {
body: Blob;
token: ?CallbackToken;
};
type CallbackToken = {
index: Nat;
};
type StreamingStrategy = {
#Callback: {
callback: query (CallbackToken) -> async (StreamingCallbackHttpResponse);
token: CallbackToken;
}
};
type HttpRequest = {
method: Text;
url: Text;
headers: [HeaderField];
body: Blob;
};
type HttpResponse = {
status_code: Nat16;
headers: [HeaderField];
body: Blob;
streaming_strategy: ?StreamingStrategy;
};
public query func streamingCallback(tk: CallbackToken): async StreamingCallbackHttpResponse{
let (payload, token) = _workContent(tk.index, 3);
{
body = payload;
token = token;
}
};
private func _workContent(index: Nat,size: Nat): (Blob, ?CallbackToken) {
let payload = Text.encodeUtf8(ans[index]);
if(index == size) return (payload, null);
(payload, ?{index = index + 1;})
};
public query func http_request(request: HttpRequest): async HttpResponse {
if(request.url == "/text") {
let (payload, token) = _workContent(1,3);
{
status_code = 200;
headers = [("Content-Type", "txt")];
body = payload;
streaming_strategy = switch(token) {
case(null) {null;};
case(?tk) {
?#Callback({
callback = streamingCallback;
token = tk;
})
}
}
}
} else {
{
status_code = 404;
headers = [];
body = Text.encodeUtf8("worng url");
streaming_strategy = null;
}
}
};
};
——示例代码来自xiaoyuanxun,有删改。
Comments 1 条评论
博客作者 zoritoler imol
Great write-up, I am regular visitor of one?¦s web site, maintain up the excellent operate, and It’s going to be a regular visitor for a long time.