Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ load("@build_bazel_rules_nodejs//:index.bzl", "pkg_npm")

pkg_npm(
name = "package",
package_name = "protoc-gen-ts",
srcs = [
"//bin:protoc-gen-ts",
"//bin:protoc-gen-ts.cmd",
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Protoc Gen Typescript

[![test](https://github.com/thesayyn/protoc-gen-ts/actions/workflows/test.yaml/badge.svg?branch=master)](https://github.com/thesayyn/protoc-gen-ts/actions/workflows/test.yaml)
![npm](https://img.shields.io/npm/v/protoc-gen-ts)
![npm bundle size](https://img.shields.io/bundlephobia/min/protoc-gen-ts)
![npm](https://img.shields.io/npm/dm/protoc-gen-ts)

Generates appropriate Protocol Buffer sources from Proto files directly through _TypeScript Compiler API_.
Expand Down Expand Up @@ -64,8 +64,6 @@ You can also support me directly by buying me one or two coffee,
<img height="40px" src="https://img.buymeacoffee.com/button-api/?text=Buy me a coffee&emoji=🙌&slug=thesayyn&button_colour=FFDD00&font_colour=000000&font_family=Cookie&outline_colour=000000&coffee_colour=ffffff">
</a>



## Key Differences

This protoc plugin does generate;
Expand Down Expand Up @@ -102,6 +100,10 @@ ts_proto_library(
```


## Usage with @grpc/grpc-js or grpc

There is a seperate documentation for the usage of protoc-gen-ts along with either `@grpc/grpc-js` or `grpc`

## Environment variables

```sh
Expand Down
10 changes: 6 additions & 4 deletions WORKSPACE
Original file line number Diff line number Diff line change
Expand Up @@ -10,18 +10,20 @@ load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
# Setup NodeJS toolchain
http_archive(
name = "build_bazel_rules_nodejs",
sha256 = "1134ec9b7baee008f1d54f0483049a97e53a57cd3913ec9d6db625549c98395a",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/3.4.0/rules_nodejs-3.4.0.tar.gz"],
sha256 = "5c40083120eadec50a3497084f99bc75a85400ea727e82e0b2f422720573130f",
urls = ["https://github.com/bazelbuild/rules_nodejs/releases/download/4.0.0-beta.0/rules_nodejs-4.0.0-beta.0.tar.gz"],
)

load("@build_bazel_rules_nodejs//:index.bzl", "node_repositories", "yarn_install")

node_repositories()
node_repositories(
node_version = "16.3.0"
)

yarn_install(
name = "npm",
package_json = "//:package.json",
yarn_lock = "//:yarn.lock",
yarn_lock = "//:yarn.lock"
)

# Setup Protocol Buffers toolchain
Expand Down
87 changes: 87 additions & 0 deletions docs/rpc.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
## Using with GRPC

This document covers basic fundamentals of using grpc classes that is generated by protoc-gen-ts.

There are not too many ways to go when it comes to using grpc with node. There are two official server implementation
of grpc for node out there. Both of them are maintained by google.

- [grpc (deprecated)](https://www.npmjs.com/package/grpc)
- [@grpc/grpc-js](@grpc/grpc-js)

this plugin generates abstract classes and rpc definitions can be consumed by these packages. all you have to do is
just write your business logic and rest will be taken care of. When you have a rpc called `Storage`, `protoc-gen-ts` will
generate two classes; `UnimplementedStorageService` and `StorageClient`.


`UnimplementedStorageService` is an abstract class
that has methods which consists of your rpc methods and an additional field called `definition`.
for each method, you will get an abstract method whose signature is 1-1 match of your rpc method.

`definition` field will have the definiton of your service which later can be passed to grpc to allocate
the appropriate endpoints for your rpc methods.

`StorageClient` will be your client to interact with this service. It consists of methods which accepts the right type of messages
to interact with the server.

Enough talking; lets implement a server that would work with any hussle.

given the proto `storage.proto`

```proto
syntax="proto3";

message Query {
string id = 1;
}

message Object {
string name = 1;
}

service Storage {
rpc get(Query) returns (Object);
}
```

you would write something for the server that looks like below
(assuming the proto output and `server.ts` is in the same directory)

```ts
import * as grpc from "@grpc/grpc-js";
import { Query, UnimplementedStorageService, Object } from "./storage";


class Storage extends UnimplementedStorageService {
get(call: grpc.ServerUnaryCall<Query, Object>, callback: grpc.requestCallback<Object>): void {
console.log(call.request.id);
callback(null, new Object({ id: call.request.id }));
}
}

const server = new grpc.Server();

server.addService(UnimplementedStorageService.definition, new Storage());


server.bindAsync(
"0.0.0.0:4884",
grpc.ServerCredentials.createInsecure(),
() => server.start()
);



```

to interact with this service you will need to use `StorageClient` as follows.

```ts
import {StorageClient, Query} from "./storage";

const storage = new StorageClient("0.0.0.0:4884", grpc.credentials.createInsecure());

storage.get(new Query(), (object) => console.log(object));

// also available as promise if the experimental promises enabled.
const object = await storage.get(new Query());
```
18 changes: 9 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"url": "https://www.buymeacoffee.com/thesayyn"
},
"scripts": {
"test": "bazel build //test:codegen && node ./scripts/sync_generated_protos.js test && bazel test //test/... --test_output=errors",
"test": "bazel build //test:codegen //test:codegen_experimental && node ./scripts/sync_generated_protos.js test && bazel test //test/... --test_output=errors",
"release": "bazel run //:package.publish -- --access public --tag latest --registry https://registry.npmjs.org",
"codegen": "node ./scripts/sync_compiler_protos.js && bazel build //src:codegen && node ./scripts/sync_generated_protos.js src/compiler && bazel build //src:compiler && node ./scripts/sync_generated_protos.js src/compiler js"
},
Expand All @@ -22,19 +22,19 @@
},
"peerDependencies": {
"google-protobuf": "^3.13.0",
"typescript": "^4.0.2"
"typescript": ">=4"
},
"devDependencies": {
"@bazel/bazelisk": "^1.7.5",
"@bazel/jasmine": "^3.4.0",
"@bazel/typescript": "^3.4.0",
"@grpc/grpc-js": "^1.2.12",
"@bazel/bazelisk": "^1.9.0",
"@bazel/jasmine": "next",
"@bazel/typescript": "next",
"@grpc/grpc-js": "^1.3.4",
"@types/google-protobuf": "^3.15.2",
"@types/jasmine": "^3.6.9",
"@types/node": "^12.12.2",
"@types/jasmine": "^3.7.7",
"@types/node": "^15.12.5",
"google-protobuf": "^3.17.3",
"jasmine": "^3.7.0",
"jasmine-core": "^3.7.1",
"typescript": "^4.0.2"
"typescript": "^4.3.4"
}
}
4 changes: 1 addition & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,9 +67,7 @@ for (const fileDescriptor of request.proto_file) {

// Create all services and clients
for (const serviceDescriptor of fileDescriptor.service) {
statements.push(rpc.createServiceInterface(fileDescriptor, serviceDescriptor, grpcIdentifier));
statements.push(rpc.createServerInterface(fileDescriptor, serviceDescriptor, grpcIdentifier));
statements.push(rpc.createService(fileDescriptor, serviceDescriptor));
statements.push(rpc.createUnimplementedServer(fileDescriptor, serviceDescriptor, grpcIdentifier));
statements.push(rpc.createServiceClient(fileDescriptor, serviceDescriptor, grpcIdentifier));
}

Expand Down
Loading