Skip to content

Remove runtime dependency on Protobuf #1386

@aslakhellesoy

Description

@aslakhellesoy

When we adopted protobuf as the basis for messages, we had 3 goals:

  • Be able to define messages with an IDL
  • Wide programming language support
  • JSON serialisation format (for debuggability)

Protobuf satisfies all of those, but has some drawbacks.

The primary drawback is runtime dependencies. The protoc code generator (or similar code generators in unofficial ports) generates code that depends on protobuf runtime libraries. This poses two challenges:

  • Size. Loading all this code into a browser take a long time because the resulting code is megabytes.
  • Compatibility. A project depending on a different version of protobuf than the one used by Cucumber might lead to conflicts

Another challenge with protobuf is maintenance cost. Because we want to inspect messages visually, we've decided to use the JSON serialisation format instead of the more commonly used binary representation. While JSON is "supported" by protobuf, the implementations have several bugs that we've had to work around or fix. These bugs exist because few people use protobuf with JSON.

During the weekly community meeting on 25 Feb 2021 two alternative solutions were put forward:

Keep .proto but use custom code generator

We could implement a custom code generator that parses the messages.proto file and reads a programming language-specific template file for code generation.

The code generator would generate code with an interface similar to the code generated by protoc, but without any runtime dependencies. It would only support JSON serialisation and not the binary representation.

For TypeScript for example, this could be just messages.d.ts (just the interface) and no implementation at all. We'd get type safety at compile time, and wouldn't need any runtime dependencies for serialisation (that would be handled by the stdlibrary JSON functions).

JSON Schema

(OpenAPI was suggested. OpenAPI has a lot of HTTP stuff in it that isn't relevant to us, and my understanding is that it relies on JSON Schema to define the schema of request/response payloads).

We could translate the .proto schema to JSON Schema and use existing tools to generate lightweight code. Here are some existing ones:

For dynamically typed languages such as Ruby, we wouldn't need code generation or any runtime dependencies at all.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions