Как в Ballerina создать буфер протокола для клиент-сервера?
Мы хотим создать репозиторий функций, который разработчик может собрать для создания сложной программы.
Может существовать несколько версий функции, каждая со своими метаданными. Эти метаданные функции включают полное имя и адрес электронной почты разработчика, язык, на котором реализована функция, и набор ключевых слов, связанных с функциональностью, выполняемой функцией.
Версии функции можно представить в виде ориентированного ациклического графа.
Для управления репозиторием мы используем gRPC на основе удаленного вызова, который позволяет клиенту взаимодействовать с сервером и выполнять следующие операции:
-
add_new_fn
: добавить новую функцию или новую версию к существующей функции; -
add_fns
: добавить несколько функций, передаваемых клиентом (обратите внимание, что несколько версий функции не разрешены); -
delete_fn
: удалить функцию (это может потребовать изменения порядка версий функции); -
show_fn
: для просмотра конкретной версии функции; -
show_all_fns
: для просмотра всех версий функции (версии возвращаются сервером) -
show_all_with_criteria
: для просмотра всех последних версий функций, реализованных на данном языке или связанных с набором ключевых слов (двунаправленная потоковая передача).
1 ответ
Предполагая, что вы просто хотите, чтобы API был определен:
syntax = "proto3";
package foo;
import "google/protobuf/any.proto";
// Convention is to name RPC method messages after the method
// Provides flexibility in evolving them distinctly too
service FnRepository {
rpc AddFn(AddFnPackageRequest) returns (AddFnPackageResponse) {}
rpc AddFns(stream
AddFnPackageRequest) returns (stream AddFnPackageResponse) {}
rpc DeleteFn(DelFnPackageRequest) returns (DelFnPackageResponse) {}
...
}
// Requests containing messages provides extensibility
message AddFnPackageRequest {
FnPackage fn_package = 1;
}
// Unique ID returned here
// Would likely be used to delete
message AddFnPackageResponse {
string id = 1;
}
message Developer {
string name = 1;
string email = 2;
}
// Enum assumes a predefined list of languages
message Fn {
string name = 1;
Signature signature = 2;
enum Language {
GOLANG = 0;
RUST = 1;
}
Language language = 3;
}
// Conceptually cleaner to define subtypes for e.g. Developer
// This does disconnect e.g. Fn from Developer
message FnPackage {
Fn fn = 1;
Developer developer = 2;
Metadata metadata = 3;
}
message Metadata {
Developer developer = 1;
repeated string keywords = 2;
}
// Any is a way to provide polymorphism
// Since Fn signatures are arbitrary types
message Signature {
google.protobuf.Any params = 1;
google.protobuf.Any return = 2;
}
...
Это полностью написано здесь, поэтому нет никаких гарантий, что он действительно скомпилируется 😃