Skip to content

Commit

Permalink
Support binding gRPC services that are defined as object literals.
Browse files Browse the repository at this point in the history
This commit allows binding gRPC services directly, in the following way:

const greeter = {
  greet: (req) => TestResponse.create({ greeting: `Hello` })
};
  • Loading branch information
igalshilman committed Sep 14, 2023
1 parent bee23ae commit 08458c0
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 8 deletions.
25 changes: 17 additions & 8 deletions src/server/base_restate_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,22 @@ export abstract class BaseRestateServer {
}
}

/* eslint-disable @typescript-eslint/no-explicit-any */
function indexProperties(instance: any): Map<string, string> {
const names = new Map<string, string>();
while (
instance !== null &&
instance !== undefined &&
instance !== Object.prototype
) {
for (const property of Object.getOwnPropertyNames(instance)) {
names.set(property.toLowerCase(), property);
}
instance = Object.getPrototypeOf(instance);
}
return names;
}

// Given:
// * an instance of a class that implements a gRPC TypeScript interface,
// as generated by our protoc plugin, this method
Expand Down Expand Up @@ -263,14 +279,7 @@ export function parseService(

// index all the existing properties that `instance` has.
// we index them by the lower case represention.
const prototype = Object.getPrototypeOf(instance);
const names = new Map<string, string>(
Object.getOwnPropertyNames(prototype).map((name) => [
name.toLowerCase(),
name,
])
);

const names = indexProperties(instance);
for (const serviceDescriptor of meta.fileDescriptor.service) {
if (serviceName !== serviceDescriptor.name) {
continue;
Expand Down
37 changes: 37 additions & 0 deletions test/service_bind.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2023 - Restate Software, Inc., Restate GmbH
*
* This file is part of the Restate SDK for Node.js/TypeScript,
* which is released under the MIT license.
*
* You can find a copy of the license in file LICENSE in the root
* directory of this repository or package, or at
* https://github.com/restatedev/sdk-typescript/blob/main/LICENSE
*/

import {
TestGreeter,
TestRequest,
TestResponse,
} from "../src/generated/proto/test";
import * as restate from "../src/public_api";
import { describe } from "@jest/globals";
import { TestDriver } from "./testdriver";
import { greetRequest, inputMessage, startMessage } from "./protoutils";

const greeter: TestGreeter = {
/* eslint-disable @typescript-eslint/no-unused-vars */
greet: async (req: TestRequest): Promise<TestResponse> => {
restate.useContext(this);
return TestResponse.create({ greeting: `Hello` });
},
};

describe("BindService", () => {
it("should bind object literals", async () => {
await new TestDriver(greeter, [
startMessage(1),
inputMessage(greetRequest("Pete")),
]).run();
});
});

0 comments on commit 08458c0

Please sign in to comment.