Our great sponsors
-
SurveyJS
Open-Source JSON Form Builder to Create Dynamic Forms Right in Your App. With SurveyJS form UI libraries, you can build and style forms in a fully-integrated drag & drop form builder, render them in your JS app, and store form submission data in any backend, inc. PHP, ASP.NET Core, and Node.js.
-
building-a-node-microservice
A repository backing the the how-to style blog post on developed a gRPC-powered service in Node.js.
-
WorkOS
The modern identity platform for B2B SaaS. The APIs are flexible and easy-to-use, supporting authentication, user identity, and complex enterprise features like SSO and SCIM provisioning.
-
InfluxDB
Power Real-Time Data Analytics at Scale. Get real-time insights from all types of time series data with InfluxDB. Ingest, query, and analyze billions of data points in real-time with unbounded cardinality.
In setting out to build this service, we wanted to use gRPC for its APIs. We’ve been reaching for REST when building APIs so far, primarily out of necessity, i.e., our public APIs needed auto-generated client SDKs and docs for developers working with them. We built those APIs with Fastify and Typebox but felt burned by a code-first approach to generating an OpenAPI spec. I’ll spare you the details and save that experience/learning for another article. Suffice it to say we love gRPC’s schema-first approach. This blog post summarizes our feelings well
You’ll need pnpm and Node.js installed on your machine + some tool for switching node versions (e.g. fnm or nvm will work fine);
You’ll need pnpm and Node.js installed on your machine + some tool for switching node versions (e.g. fnm or nvm will work fine);
All of the code examples in this article are taken from the following repository ‣. Each part of the post should have a corresponding commit in the repository's main branch.
In setting out to build this service, we wanted to use gRPC for its APIs. We’ve been reaching for REST when building APIs so far, primarily out of necessity, i.e., our public APIs needed auto-generated client SDKs and docs for developers working with them. We built those APIs with Fastify and Typebox but felt burned by a code-first approach to generating an OpenAPI spec. I’ll spare you the details and save that experience/learning for another article. Suffice it to say we love gRPC’s schema-first approach. This blog post summarizes our feelings well
Pnpm has built-in support for monorepos via pnpm workspaces. We’ll configure pnpm-workspace.yaml as follows.
protobuf messages we’ll configure (@bufbuild/connect-es)
And we will once use unbuild to build.
import { StateTransitionService } from "@state-transitions/definition"; import { createConnectTransport } from "@bufbuild/connect-node"; import { createPromiseClient } from "@bufbuild/connect"; // The following line is due to these issues // > https://github.com/aspect-build/rules_ts/issues/159#issuecomment-1437399901 // > https://github.com/microsoft/TypeScript/issues/47663#issuecomment-1270716220 import type {} from "@bufbuild/protobuf"; export const transport = createConnectTransport({ baseUrl: `http://localhost:8080`, httpVersion: "1.1", }); export const client = createPromiseClient(StateTransitionService, transport);
import { StateTransitionService } from "@state-transitions/definition"; import { createConnectTransport } from "@bufbuild/connect-node"; import { createPromiseClient } from "@bufbuild/connect"; // The following line is due to these issues // > https://github.com/aspect-build/rules_ts/issues/159#issuecomment-1437399901 // > https://github.com/microsoft/TypeScript/issues/47663#issuecomment-1270716220 import type {} from "@bufbuild/protobuf"; export const transport = createConnectTransport({ baseUrl: `http://localhost:8080`, httpVersion: "1.1", }); export const client = createPromiseClient(StateTransitionService, transport);
As we iterate on the definition, we are going to want a better developer experience for rebuilding the package on changes. Typically, for a “library” or “utility” style package, I’d reach for either unbuild’s stub concept or use esbuild/tsup/rollup to implement a more traditional watch/rebuild, but in this case, I’m watching a proto file that lives outsides of the source, which breaks assumptions of those tools.
As we iterate on the definition, we are going to want a better developer experience for rebuilding the package on changes. Typically, for a “library” or “utility” style package, I’d reach for either unbuild’s stub concept or use esbuild/tsup/rollup to implement a more traditional watch/rebuild, but in this case, I’m watching a proto file that lives outsides of the source, which breaks assumptions of those tools.
As we iterate on the definition, we are going to want a better developer experience for rebuilding the package on changes. Typically, for a “library” or “utility” style package, I’d reach for either unbuild’s stub concept or use esbuild/tsup/rollup to implement a more traditional watch/rebuild, but in this case, I’m watching a proto file that lives outsides of the source, which breaks assumptions of those tools.
As mentioned in the intro, we are going to use Buf and Connect as our tools. We’ll start by installing the dependencies.
As mentioned in the intro, we are going to use Buf and Connect as our tools. We’ll start by installing the dependencies.