Ballerina,使用来自REST API的Json响应

3

我的教授希望我写一个有关如何部署Ballerina服务的小型教程,所以我正在学习它。我使用的是1.2版本,对于污点检查和变量类型的概念有些不知所措...

我正在尝试编写一个最小化的REST服务,其中一个端点从另一个API请求JSON数据,然后使用该JSON来执行操作。

到目前为止,以下功能已经可以正常工作:

service tutorial on new http:Listener(9090) {

    // Resource functions are invoked with the HTTP caller and the incoming request as arguments.
    resource function getName(http:Caller caller, http:Request req) {
   http:Client clientEP = new("https://api.scryfall.com/");

    var resp = clientEP->get("/cards/random");
    if (resp is http:Response) {

        var payload = resp.getJsonPayload();

        if (payload is json) {

            var result = caller->respond(<@untainted>(payload));
        } else {

            log:printError("");
        }
    } else {

        log:printError("");
    }
}

响应的JSON来自https://api.scryfall.com/cards/random

但是现在,假设我想从该JSON中访问单个值,例如“name”。 如果我尝试像这样访问它:payload ["name"]

我得到:无效操作:类型“json”不支持索引

我刚刚发现,如果先创建一个map,就可以正常访问,像这样:

map mp = <map> payload;

然后如果我访问mp ["name"],它就可以了。但为什么?如果您仍然必须创建一个map,然后转换负载,那么json类型有什么用处?如何访问json内部的json?例如mp ["data"] [0] ...再次出现无效操作:类型'json'不支持索引...

我仍然在努力理解污点检查的概念...... 在检查内容后,我是否只需将所有受污染的内容强制转换为<@untainted>? 有时我真的不明白文档试图告诉我的是什么....

1个回答

3
我建议您使用Ballerina Swan Lake版本。 Swan Lake版本包含对各种语言功能的增强。以下是一个示例代码,涵盖了您的用例。您可以在https://ballerina.io/下载Swan Lake Alpha2。
import ballerina/io;
import ballerina/http;

service tutorial on new http:Listener(9090) {
    resource function get payload() returns json|error {
        http:Client clientEP = check new ("https://api.scryfall.com/");
        json payload = <json> check clientEP -> get("/cards/random", targetType = json);

        // Processing the json payload 
        // Here the type of the `payload.name` expression is json | error
        // You can eliminate with check: it returns from this resource with this error
        json nameField = check payload.name;
        io:println(nameField);

        // You can traverse the json tree as follows
        json standardLegality = check payload.legalities.standard;
        io:println(standardLegality);

        // colors is an array 
        // The cast is necessary because `check payload.colors` gives you a json
        json colors = <json[]> check payload.colors;
        io:println(colors);

        // Responding with the complete payload recived from api.scryfall.com
        return payload;
    }
}

污点分析有助于编写没有安全漏洞的代码。然而,在天鹅湖版本中,我们已禁用了污点分析。如果您想启用它,可以在bal build命令中使用选项--taint-check


补充Sameera的回答,如果您需要更多关于Ballerina中污点检查的信息,请参考以下博客文章:https://medium.com/ballerina-techblog/ballerina-taint-checking-guide-553ec9b8f153。 - Anjana Fernando
谢谢你迄今为止的帮助...我已经切换到了天鹅湖 - 但是所有不同类型、类型转换等仍然让我感到困惑...代码运行良好,但我真的不明白为什么...或者说:我知道这个例子为什么能工作,但当它变得更加复杂时,我仍然感到迷茫...假设现在我有一个字段payload.data,它包含多个JSON对象。现在假设我想要访问第一个对象。当我执行payload.data[0].name;时,我会得到类型“json”不支持索引。这怎么可能?有点令人沮丧,我没有理解这样基本的概念...@Sameera - Jan-Ole Hübner
明白了...与以下工作:json[] data = <json[]> check payload.data; 强制转换这么多感觉不太好...这会是不好的做法吗? - Jan-Ole Hübner
1
当前的设计要求在需要时执行所需的强制转换。因此你提出的建议是正确的。 - Anjana Fernando

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接