核心要点
该教程阐述了 Ballerina, 这是一个新的编程语言和平台, 它的目标在于让创建具有弹性的服务变得更加容易, 这些服务会跨分布式端点进行集成和编排.
Ballerina .970 已经释放, 语言的稳定性会不断提升, 有望在 2108 年底发布 1.0;
Ballerina 现在托管在该站点上 https://ballerina.io/ , 包括包管理, 依赖管理, 版本化, Ballerina Central 上有一个全局托管的注册表, 用于连接器 (connector) 和注解(annotation).
Ballerina 的设计原则在于将集成的概念转换为一种语言, 包括一个网络感知的类型系统, 序列图语法, 并发工作者, 为 "采用 DevOps 做好准备" 以及环境感知.
Ballerina 是一种让微服务编程更加简单的方式, 它通过简化集成 API 来实现这一点. Ballerina 是三年前由 WSO2 的架构师发起的, 在与 EAI,ESB 和工作流产品构建集成时, 他们遇到了各种挑战, Ballerina 则是他们对此给出的响应.
关于 Ballerina
开发一种新的编程语言和运行时技术栈并不是一件常见的事情. Ballerina 起源于项目领导者在进行项目集成时所遇到的挫败感, 这种集成的工作越来越多地干扰了开发人员的常规工作流程, 即周而复始地编辑, 构建, 测试.
- // Packages contain functions, annotations and
- // connectors. This package is referenced by
- // 'http' namespace in the code body.
- import ballerina/http;
- import ballerina/io;
- // A service is a network-accessible API. This
- // service accessible at '/hello', and bound to a
- // default listener on port 9090. `http:Service`
- // is a connector in the `http` package.
- service<http:Service> hello bind {port:9090} {
- // A resource is an invokable API method
- // Accessible at '/hello/hi'
- // 'caller' is the client invoking this resource
- hi (endpoint caller, http:Request request) {
- // Create object to carry data back to caller
- http:Response response = new;
- // Objects have function calls
- response.setPayload("Hello Ballerina!\n");
- // Send a response back to caller
- // Errors are ignored with '_'
- // '->' is a synchronous network-bound call
- _ = caller -> respond(response);
- }
- }
- any anything; // can be any type
- int integer = 0;
- float floatingPoint = 0.0;
- // constants are final instances of a type
- @final float PI = 3.1415926;
- boolean b = true;
- string hi = "hello";
- blob bl = hi.toBlob("UTF-8");
- // json is a primitive
- json js = {
- a: "hello",
- b: 5
- };
- // xml is a primitive
- xml x = xml `<ballerina>
- <supports>XML natively</supports>
- </ballerina>`;
- // type inference
- var x = xml `<myXML/>`;
- // errors are built in types
- error e;
- string[] stringArray = ["hi", "there"];
- int[][] arrayOfArrays = [[1,2],[3,4]];
- // union and tuple types
- json | xml | string networkResponse;
- (string, int) tuple = ("hello", 5);
- () n = (); // the empty tuple is "null"
- string | int stringOrInt = 5;
- // maps are built in
- map<boolean> myMap = {"ballerina": true};
- // new types can be declared
- // a "record" type is a simple structure
- type myRecord { string a; int b; };
- // records can be converted to/from JSON with error handling
- rec | error myRec = <rec>j;
- // you can re-declare existing types
- type myInt int;
- // objects have public and private fields, initialisers and logic
- type myObj object {
- public { string x; }
- private { string y; }
- new (string a, string b) {
- x = a; y = b;
- }
- function getY() {
- return y;
- }
- };
- // enumerations are union types:
- type aOrB "A" | "B";
- aOrB myEnum = "A";
- aOrB compilationError = "C"; // this won't compile due to type checking
- // streams are first-class types
- stream<obj> str;
- // futures are built in types for asynchronous activities
- future<string> f;
- // functions are types and support lambda expressions
- function (string, int) returns (string) func =
- (string x, int i) => (string) { return "lambda"; };
- import ballerina/http;
- import ballerina/io;
- import ballerina/runtime;
- @http:ServiceConfig {
- basePath:"/quote"
- }
- service<http:Service> AsyncInvoker bind {} {
- @http:ResourceConfig {
- methods:["GET"],
- path:"/"
- }
- getQuote (endpoint caller, http:Request req) {
- // 'endpoint' declares a connection to a networked location.
- endpoint http:SimpleClient nasdaqServiceEP {
- url:"http://localhost:9095"
- };
- io:println(">> Invoking service asynchronounsly...");
- // 'start' allows you to invoke a function or client
- // connector action asynchronously. This is a remote
- // invocation that returns without waiting for response.
- future<http:Response | http:HttpConnectorError> f1
- = start nasdaqServiceEP
- -> get("/nasdaq/quote/GOOG", new);
- io:println(">> Invocation completed!"
- + "Proceed without blocking for a response.");
- io:println(">> Check for response availability...");
- // 'await` blocks until the previously started
- // async function returns.
- var response = await f1;
- io:println(">> Response available!");
- match response {
- http:Response resp => {
- string responseStr = check resp.getStringPayload();
- io:println(">> Response :"
- + responseStr);
- _ = caller -> respond(resp);
- }
- http:HttpConnectorError err => {
- io:println(err.message);
- }
- }
- }
- }
- import ballerina/io;
- function main (string... args) {
- worker w1 {
- int i = 100;
- float k = 2.34;
- // Pass variables to w2
- (i, k) -> w2;
- json j = {};
- // Receive a message from w2
- j <- w2;
- }
- worker w2 {
- int iw;
- float kw;
- any vW1;
- // Receive a message from w1
- vW1 <- w1;
- (iw, kw) = check <(int, float)>vW1;
- json jw = {"name":"Ballerina"};
- // Send a message to w1
- jw -> w1;
- }
- }
- $ tree
- /
- .ballerina/ # Dependencies downloaded and cached locally
- Ballerina.toml # Defines project build intent
- my.package/ # Any folder is a package
- RouterService.bal
- tests/
- RouterTests.bal
- $ ballerina build
- Pulling dependencies...
- ballerinax/http [central.ballerina.io -> home repo] [====>] 56/56
- ballerinax/rpc [central.ballerina.io -> home repo] [====>] 98/98
- ballerinax/twitter [central.ballerina.io -> home repo] [====>] 79/79
- Building binaries...
- something.bal target/something.balo
- something.bal target/something.balo
- something.bal target/something.balo
- Running tests...
- Test <mytest> RUNNING ... SUCCESS
- Test <mytest> RUNNING ... SUCCESS
- Test <mytest> RUNNING ... SUCCESS
- Generating deployment artifacts...
- @docker - complete 1/1
- @kubernetes:ingress - complete 3/3
- @kubernetes:svc - complete 3/3
- @kubernetes:deployment - complete 1/1
- SUCCESS
- $ ballerina run
- Service ready at http://192.168.1.101/customer
- $ ballerina run kubernetes
- Service ready at http://wso2.com:4056/customer
- // Packages contain functions, annotations and
- // connectors. This package is referenced by
- // 'http' namespace in the code body.
- import ballerina/http;
- import ballerina/io;
- // A connector to a REST endpoint with a circuit
- // breaker that will be compiled into the service
- endpoint http:Client homer {
- targets : [{url:"http://www.simpsonquotes.xyz"}],
- circuitBreaker: {
- failureThreshold:0,
- resetTimeMillies:3000,
- statusCodes:[400, 404, 500]
- },
- timeoutMillis:500
- };
- @kubernetes:Deployment {
- image: "demo/home-demo",
- name: "homer-demo"
- }
- @kubernetes:Service {
- serviceType:"NodePort",
- name:"homer-demo"
- }
- service<http:Service> hello bind {port:9090} {
- hi (endpoint caller, http:Request request) {
- // The 'check' operator will propagate any error
- string name = check homer -> get ("/quote");
- http:Response response = new;
- response.setPayload("Hello Ballerina!\n");
- _ = caller -> respond(response);
- }
- }
- Ballerina Central
- // Create a project with a package
- // Subfolders are packages
- ballerina init
- // Search local repositories and Ballerina central for packages
- ballerina search
- ballerina pull <org-name>/<package-name>
- // Push your packages up to Ballerina Central
- // Kicks off an oAuth authorization flow in your browser to
- // obtain a CLI key that is installed onto your system
- ballerina push <org-name>/<package-name>
来源: http://www.infoq.com/cn/articles/ballerina-microservices-language-part-1