IDL檔案
接口描述語言(interface description language),通過一種中立的方式來描述接口,使得在不同的平台上運作的對象和不同語言編寫的程式可以互相通信交流。比如你用Java語言實作提供的一個服務,也能被PHP語言調用。
也就是說IDL主要是用作跨語言平台的服務之間的調用,有兩種最常用的IDL
- Facebook開源的Thrift協定
- Google開源的gRPC協定
以gRPC協定為例使用IDL檔案方式來描述接口。
gRPC協定使用Protobuf簡稱proto檔案來定義接口名、調用參數以及傳回值類型。
比如檔案helloword.proto定義了一個接口SayHello方法,它的請求參數是HelloRequest,它的傳回值是HelloReply。
// The greeter service definition.
service Greeter {
// Sends a greeting
rpc SayHello (HelloRequest) returns (HelloReply) {}
rpc SayHelloAgain (HelloRequest) returns (HelloReply) {}
}
// The request message containing the user's name.
message HelloRequest {
string name = 1;
}
// The response message containing the greetings
message HelloReply {
string message = 1;
}
假如服務提供者使用的是Java語言,那麼利用protoc插件即可自動生成Server端的Java代碼。
private class GreeterImpl extends GreeterGrpc.GreeterImplBase {
@Override
public void sayHello(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
HelloReply reply = HelloReply.newBuilder().setMessage("Hello " + req.getName()).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
@Override
public void sayHelloAgain(HelloRequest req, StreamObserver<HelloReply> responseObserver) {
HelloReply reply = HelloReply.newBuilder().setMessage("Hello again " + req.getName()).build();
responseObserver.onNext(reply);
responseObserver.onCompleted();
}
}
假如服務消費者使用的也是Java語言,那麼利用protoc插件即可自動生成Client端的Java代碼。
public void greet(String name) {
logger.info("Will try to greet " + name + " ...");
HelloRequest request = HelloRequest.newBuilder().setName(name).build();
HelloReply response;
try {
response = blockingStub.sayHello(request);
} catch (StatusRuntimeException e) {
logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
return;
}
logger.info("Greeting: " + response.getMessage());
try {
response = blockingStub.sayHelloAgain(request);
} catch (StatusRuntimeException e) {
logger.log(Level.WARNING, "RPC failed: {0}", e.getStatus());
return;
}
logger.info("Greeting: " + response.getMessage());
}
gRPC協定的服務描述是通過proto檔案來定義接口,然後再使用protoc來生成不同語言平台的用戶端和服務端代碼,進而跨語言服務調用。
在描述接口定義時,IDL檔案需要對接口傳回值進行詳細定義。如果接口傳回值的字段比較多,并且經常變化時,采用IDL檔案方式的接口定義就不太合适了。一方面可能會造成IDL檔案過大難以維護,另一方面隻要IDL檔案中定義的接口傳回值有變更,都需要同步所有的服務消費者都更新,管理成本太高。
總結
通常情況下,如果隻是企業内部之間的服務調用,并且都是Java,選擇XML配置最簡單。
如果企業内部存在多個服務,并且服務采用的是不同語言平台,建議使用IDL檔案方式進行描述服務。
如果還存在對外開放服務調用的情形的話,使用RESTful API方式則更加通用。