ballerina 学习二十 http/https

提供http && https server && client 访问功能

client endpoint

说白了就是http client

  • 参考代码
import ballerina/http;
import ballerina/log;endpoint http:Client clientEndpoint {
    url: "https://postman-echo.com"
};function main(string... args) { http:Request req = new;
    var response = clientEndpoint->get("/get?test=123"); match response {
        http:Response resp => {
            log:printInfo("GET request:");
            var msg = resp.getJsonPayload();
            match msg {
                json jsonPayload => {
                    log:printInfo(jsonPayload.toString());
                }
                error err => {
                    log:printError(err.message, err = err);
                }
            }
        }
        error err => { log:printError(err.message, err = err); }
    }
    req.setPayload("POST: Hello World"); response = clientEndpoint->post("/post", request = req);
    match response {
        http:Response resp => {
            log:printInfo("
POST request:");
            var msg = resp.getJsonPayload();
            match msg {
                json jsonPayload => {
                    log:printInfo(jsonPayload.toString());
                }
                error err => {
                    log:printError(err.message, err = err);
                }
            }
        }
        error err => { log:printError(err.message, err = err); } }
    json jsonMsg = { method: "PUT", payload: "Hello World" };
    req.setJsonPayload(jsonMsg); response = clientEndpoint->put("/put", request = req);
    match response {
        http:Response resp => {
            log:printInfo("
PUT request:");
            var msg = resp.getJsonPayload();
            match msg {
                json jsonPayload => {
                    log:printInfo(jsonPayload.toString());
                }
                error err => {
                    log:printError(err.message, err = err);
                }
            }
        }
        error err => { log:printError(err.message, err = err); }
    }
    xml xmlMsg = xml `<request>
                        <method>PATCH</method>
                        <payload>Hello World!</payload>
                      </request>`;
    req.setXmlPayload(xmlMsg); response = clientEndpoint->patch("/patch", request = req);
    match response {
        http:Response resp => {
            log:printInfo("
PATCH request:");
            var msg = resp.getJsonPayload();
            match msg {
                json jsonPayload => {
                    log:printInfo(jsonPayload.toString());
                }
                error err => {
                    log:printError(err.message, err = err);
                }
            }
        }
        error err => { log:printError(err.message, err = err); }
    } req.setPayload("DELETE: Hello World");
    response = clientEndpoint->delete("/delete", request = req);
    match response {
        http:Response resp => {
            log:printInfo("
DELETE request:");
            var msg = resp.getJsonPayload();
            match msg {
                json jsonPayload => {
                    log:printInfo(jsonPayload.toString());
                }
                error err => {
                    log:printError(err.message, err = err);
                }
            }
        }
        error err => { log:printError(err.message, err = err); }
    } req.setPayload("CUSTOM: Hello World");
    response = clientEndpoint->execute("COPY", "/get", req); req = new;
    req.addHeader("Sample-Name", "http-client-connector");
    response = clientEndpoint->get("/get", request = req);
    match response {
        http:Response resp => {
            string contentType = resp.getHeader("Content-Type");
            log:printInfo("
Content-Type: " + contentType); int statusCode = resp.statusCode;
            log:printInfo("Status code: " + statusCode); }
        error err => { log:printError(err.message, err = err); }
    }
}
  • 输出结果
2018-06-01 21:03:32,032 INFO [] - GET request:
2018-06-01 21:03:32,059 INFO [] - {"args":{"test":"123"},"headers":{"host":"postman-echo.com","user-agent":"ballerina/0.970.1","x-forwarded-port":"443","x-forwarded-proto":"https"},"url":"https://postman-echo.com/get?test=123"}
2018-06-01 21:03:32,633 INFO [] -
POST request:
2018-06-01 21:03:32,636 INFO [] - {"args":{},"data":"POST: Hello World","files":{},"form":{},"headers":{"host":"postman-echo.com","content-length":"17","content-type":"text/plain","user-agent":"ballerina/0.970.1","x-forwarded-port":"443","x-forwarded-proto":"https"},"json":null,"url":"https://postman-echo.com/post"}
2018-06-01 21:03:33,349 INFO [] -
PUT request:
2018-06-01 21:03:33,351 INFO [] - {"args":{},"data":{"method":"PUT","payload":"Hello World"},"files":{},"form":{},"headers":{"host":"postman-echo.com","content-length":"40","content-type":"application/json","user-agent":"ballerina/0.970.1","x-forwarded-port":"443","x-forwarded-proto":"https"},"json":{"method":"PUT","payload":"Hello World"},"url":"https://postman-echo.com/put"}
2018-06-01 21:03:33,861 INFO [] -
PATCH request:
2018-06-01 21:03:33,863 INFO [] - {"args":{},"data":"<request>
 <method>PATCH</method>
 <payload>Hello World!</payload>
 </request>","files":{},"form":{},"headers":{"host":"postman-echo.com","content-length":"145","content-type":"application/xml","user-agent":"ballerina/0.970.1","x-forwarded-port":"443","x-forwarded-proto":"https"},"json":null,"url":"https://postman-echo.com/patch"}
2018-06-01 21:03:34,373 INFO [] -
DELETE request:
2018-06-01 21:03:34,375 INFO [] - {"args":{},"data":"DELETE: Hello World","files":{},"form":{},"headers":{"host":"postman-echo.com","content-length":"19","content-type":"text/plain","user-agent":"ballerina/0.970.1","x-forwarded-port":"443","x-forwarded-proto":"https"},"json":null,"url":"https://postman-echo.com/delete"}
2018-06-01 21:03:35,193 INFO [] -
Content-Type: application/json; charset=utf-8
2018-06-01 21:03:35,193 INFO [] - Status code: 200

http client redirect

redirect 是服务器端的相应,一般http 客户端不会进行处理,ballerina 有可选的配置参数,同时可以设置最大次数(防止死循环)

  • 参考代码
import ballerina/io;
import ballerina/http;
import ballerina/log;
import ballerina/mime;endpoint http:Client clientEP {
    url: "http://localhost:9090",
    followRedirects: { enabled: true, maxCount: 5 }
};
function main(string... args) {
    var returnResult = clientEP->get("/redirect1");

    match returnResult {
        error connectionErr => log:printError("Error in connection",
            err = connectionErr);
        http:Response resp => {
            match resp.getTextPayload() {
                error e => log:printError("Error in payload", err = e);
                string payload => io:println("Response received : " + payload);
            }
        }
    }
}
@http:ServiceConfig {
    basePath:"/redirect1"
}
service<http:Service> redirect1 bind {port:9090} { @http:ResourceConfig {
        methods:["GET"],
        path:"/"
    }
    redirect1 (endpoint client, http:Request req) {
        http:Response res = new;
        _ = client -> redirect(res, http:REDIRECT_TEMPORARY_REDIRECT_307,
            ["http://localhost:9093/redirect2"]);
    }
}@http:ServiceConfig {
    basePath:"/redirect2"
}
service<http:Service> redirect2 bind {port:9093} { @http:ResourceConfig {
        methods:["GET"],
        path:"/"
    }
    redirect2 (endpoint client, http:Request req) {
        http:Response res = new;
        res. setPayload("Hello World!");
        _ = client -> respond( res) but { error e => log:printError("Error in
        responding", err = e) };
    }
}

## http server base path && params

  • 参考代码
import ballerina/http;
import ballerina/log;
import ballerina/mime;
@http:ServiceConfig { basePath: "/foo" }
service<http:Service> echo bind { port: 9090 } {
    @http:ResourceConfig {
        methods: ["POST"],
        path: "/bar"
    }
    echo(endpoint caller, http:Request req) {
        var result = req.getJsonPayload();
        http:Response res = new;
        match result {
            error err => {
                res.statusCode = 500;
                res.setPayload(err.message);
            }
            json value => {
                res.setJsonPayload(value);
            }
        }
        caller->respond(res) but {
            error e => log:printError("Error in responding", err = e)
        };
    }
}

import ballerina/http;
import ballerina/log;@http:ServiceConfig
service<http:Service> sample bind { port: 9090 } { @http:ResourceConfig {
        methods: ["GET"],
        path: "/path/{foo}"
    }
    params(endpoint caller, http:Request req, string foo) {
        var params = req.getQueryParams();
        var bar = <string>params.bar;
        map pathMParams = req.getMatrixParams("/sample/path");
        var a = <string>pathMParams.a;
        var b = <string>pathMParams.b;
        string pathMatrixStr = string `a={{a}}, b={{b}}`;
        map fooMParams = req.getMatrixParams("/sample/path/" + foo);
        var x = <string>fooMParams.x;
        var y = <string>fooMParams.y;
        string fooMatrixStr = string `x={{x}}, y={{y}}`;
        json matrixJson = { "path": pathMatrixStr, "foo": fooMatrixStr };
        json responseJson = { "pathParam": foo, "queryParam": bar, "matrix": matrixJson };
        http:Response res = new;
        res.setJsonPayload(responseJson);
        caller->respond(res) but { error e => log:printError("Error when responding", err = e) };
    }
}

https server

  • 参考代码
import ballerina/http;
import ballerina/log;
endpoint http:Listener helloWorldEP {
    port: 9095,
    secureSocket: {
        keyStore: {
            path: "${ballerina.home}/bre/security/ballerinaKeystore.p12",
            password: "ballerina"
        }
    }
};
@http:ServiceConfig {
    basePath: "/hello"
}
service helloWorld bind helloWorldEP {
    @http:ResourceConfig {
        methods: ["GET"],
        path: "/"
    } 
 sayHello(endpoint caller, http:Request req) {
        http:Response res = new;
        res.setPayload("Hello World!");
        caller->respond(res) but {
                    error e => log:printError("Error in responding ", err = e) };
    }
}

cors

一般进行跨域处理

  • 参考代码
import ballerina/http;
import ballerina/log;
@http:ServiceConfig {
    cors: {
        allowOrigins: ["http://www.m3.com", "http://www.hello.com"],
        allowCredentials: false,
        allowHeaders: ["CORELATION_ID"],
        exposeHeaders: ["X-CUSTOM-HEADER"],
        maxAge: 84900
    }
}
service<http:Service> crossOriginService bind { port: 9092 } { string respErr = "Failed to respond to the caller";
    @http:ResourceConfig {
        methods: ["GET"],
        path: "/company",
        cors: {
            allowOrigins: ["http://www.bbc.com"],
            allowCredentials: true,
            allowHeaders: ["X-Content-Type-Options", "X-PINGOTHER"]
        }
    }
    companyInfo(endpoint caller, http:Request req) {
        http:Response res = new;
        json responseJson = { "type": "middleware" };
        res.setJsonPayload(responseJson);
        caller->respond(res) but { error e => log:printError(respErr, err = e) };
    }
    @http:ResourceConfig {
        methods: ["POST"],
        path: "/lang"
    }
    langInfo(endpoint caller, http:Request req) {
        http:Response res = new;
        json responseJson = { "lang": "Ballerina" };
        res.setJsonPayload(responseJson);
        caller->respond(res) but { error e => log:printError(respErr, err = e) };
    }
}

数据绑定

http body 序列化

  • 参考代码
import ballerina/http;
import ballerina/io;
import ballerina/log;type Student {
    string Name;
    int Grade;
    map Marks;
};
@http:ServiceConfig
service<http:Service> hello bind { port: 9090 } { string respErr = "Failed to respond to the caller";
    @http:ResourceConfig {
        methods: ["POST"],
        body: "orderDetails"
    }
    bindJson(endpoint caller, http:Request req, json orderDetails) {
        json details = orderDetails.Details; http:Response res = new;
        res.setPayload(details);
        caller->respond(res) but { error e => log:printError(respErr, err = e) };
    }
    @http:ResourceConfig {
        methods: ["POST"],
        body: "store",
        consumes: ["application/xml"]
    }
    bindXML(endpoint caller, http:Request req, xml store) {
        xml city = store.selectDescendants("{http://www.test.com}city"); http:Response res = new;
        res.setPayload(city);
        caller->respond(res) but { error e => log:printError(respErr, err = e) };
    }
    @http:ResourceConfig {
        methods: ["POST"],
        body: "student",
        consumes: ["application/json"]
    }
    bindStruct(endpoint caller, http:Request req, Student student) {
        string name = student.Name; int grade = student.Grade; http:Response res = new;
        res.setPayload({ Name: name, Grade: grade });
        caller->respond(res) but { error e => log:printError(respErr, err = e) };
    }
}

参考资料

https://ballerina.io/learn/by-example/http-client-endpoint.html
https://ballerina.io/learn/by-example/https-listener.html
https://ballerina.io/learn/by-example/http-cors.html
https://ballerina.io/learn/by-example/http-data-binding.html

原文地址:https://www.cnblogs.com/rongfengliang/p/9123694.html