Skip to content

[feat][client] Expose Client.getSchemaInfo - #512

Merged
gaoran10 merged 2 commits into
apache:masterfrom
dev-ankit:feat/client-get-schema-info
Oct 30, 2026
Merged

gaoran10 merged 2 commits into
apache:masterfrom
dev-ankit:feat/client-get-schema-info

Conversation

@dev-ankit

@dev-ankit dev-ankit commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #362

Follow-up to #509, which exposed Message.getLongSchemaVersion().

Motivation

A consumer of an Avro or JSON topic needs the writer schema of each message to decode messages produced with an older, compatible schema. #509 gives the consumer the writer schema version. This PR lets it fetch the schema for that version over the binary protocol, without an admin REST call. The bundled C++ client already provides Client::getSchemaInfoAsync(topic, version, callback), but the Node client does not expose it.

Modifications

  • src/Client.h, src/Client.cc, src/Client.js: add Client.getSchemaInfo(topic, version). It wraps Client::getSchemaInfoAsync and returns a promise. The name follows the C++ method without the Async suffix, as getPartitionsForTopic and close do. A missing topic or version rejects with Failed to get schema info: <result>. A topic that isn't a string, or a version that isn't a non-negative safe integer, throws a TypeError rather than being coerced to a different version.
  • src/SchemaInfo.h, src/SchemaInfo.cc: convert a pulsar::SchemaInfo into the JS SchemaInfo object (schemaType, name, schema, properties) using the existing schemaType name table. A schema type with no entry in the table rejects instead of returning a name the typings don't allow.
    • schema is returned as a Buffer of the raw schema data, as in the C++ (std::string) and Java (byte[]) clients. KeyValue schema data is binary, and a UTF-8 string would replace its length prefixes with U+FFFD.
    • The schema option of producers and consumers now also accepts a Buffer, so a fetched schema can be passed back as-is. Strings work as before.
    • Schema properties are defined as own properties, so a __proto__ key is kept.
  • index.d.ts: declare getSchemaInfo(topic: string, version: number): Promise<SchemaInfo & { schema: Buffer }> on Client, and widen SchemaInfo.schema to string | Buffer.
  • tstest.ts: add a typing check for the new method.
  • tests/client.test.js: add the getSchemaInfo tests.

Verifying this change

  • Make sure that the change passes the CI checks.

This change added tests and can be verified as follows:

  • Added the test Client/getSchemaInfo. It:
    • produces on a fresh topic with Avro schema V1 and then with a compatible schema V2 (V1 plus a field with a default);
    • calls getSchemaInfo with each received message's getLongSchemaVersion(), and asserts it returns schemaType: 'Avro' and the matching schema definition;
    • asserts a version that doesn't exist rejects with Failed to get schema info: .
  • Added the test KeyValue schema. It registers a KeyValue schema whose key schema is longer than 127 bytes through the admin API, fetches it, and asserts the binary layout decodes to the original key and value schemas. It then creates a producer with the fetched schema and asserts the broker registers no new version.
  • Added the test Schema properties, which asserts properties, including a __proto__ key, come back as registered.
  • Added the test Invalid arguments, which asserts a missing version, 0.5, -1, NaN, Infinity, 2 ** 53 and '0' throw.

Locally, Client/getSchemaInfo fails if the binding ignores version and always fetches version 0, and Schema properties fails if properties are assigned with Set.

Documentation

  • doc-required

  • doc-not-needed
    (New Client method, documented in index.d.ts, which generates the API reference. The client feature matrix has no row for this.)

  • doc

  • doc-complete

Created with Claude Opus 5.5 in Claude Code.

Add Client.getSchemaInfo(topic, version), which fetches the schema
registered for a topic at a given version. It wraps the C++ client's
Client::getSchemaInfoAsync and resolves to the same SchemaInfo shape
that producers and consumers accept.

Together with Message.getLongSchemaVersion() (apache#509), a consumer can look
up the writer schema of each message and decode messages produced with
an older, compatible schema.

Master Issue: apache#362

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The change silently drops registered __proto__ schema properties and accepts invalid numeric versions that can return the wrong writer schema.

2 open issues
What changed in this PR

Exposes Client.getSchemaInfo(topic, version) so consumers can retrieve a message’s writer schema over the binary protocol. This complements the schema-version access added in #509 and supports manual decoding across schema evolution.

Changes:

  • Adds a promise-based schema lookup through the JavaScript and native client layers.
  • Converts native schema information into the existing JavaScript SchemaInfo shape.
  • Adds TypeScript declarations and tests for versioned lookup and invalid arguments.
File Description
tstest.ts Checks the new method’s TypeScript return type.
tests/​client.test.js Tests schema evolution, missing versions, and invalid arguments.
src/​SchemaInfo.h Declares schema conversion helpers.
src/​SchemaInfo.cc Converts schema types, definitions, and metadata into JavaScript objects.
src/​Client.js Exposes the JavaScript forwarding method.
src/​Client.h Declares the native binding method.
src/​Client.cc Implements asynchronous lookup and promise resolution or rejection.
index.d.ts Declares and documents the public API.

Review effort: Balanced

Comment thread src/Client.cc Resolved
Comment thread src/SchemaInfo.cc Resolved
@gaoran10

gaoran10 commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

Could you add a test for fetching a KeyValue schema with getSchemaInfo() and verify that the binary schema data is preserved? The current UTF-8 string conversion may corrupt the binary length fields in KeyValue schemas.

…ents

- Return the schema data from getSchemaInfo as a Buffer. KeyValue schema
  data is binary, and converting it to a UTF-8 string replaced its length
  prefixes with U+FFFD. Accept a Buffer as the schema option too, so a
  fetched schema can be passed back to a producer or consumer.
- Reject a schema version that is not a non-negative safe integer.
  Int64Value() turned 0.5, -1 or NaN into a different, existing version.
- Define schema properties as own properties, so a "__proto__" key is
  not dropped by the prototype setter.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@dev-ankit

Copy link
Copy Markdown
Contributor Author

@gaoran10 yes added a test and conversion does corrupt it. changing getSchemaInfo to return schema as a Buffer of the raw bytes, as the C++ and Java clients do.

@gaoran10 gaoran10 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@gaoran10
gaoran10 merged commit b4010fa into apache:master Oct 30, 2026
12 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add method to get the schema (version) used for serialization of a message

3 participants