Skip to content

Commit

Permalink
Merge pull request #9 from debitoor/fix-review-comments-2
Browse files Browse the repository at this point in the history
fix-review-comments-2
  • Loading branch information
bifrost authored Oct 3, 2022
2 parents 8a34858 + d94bcc4 commit 3d2e0bb
Show file tree
Hide file tree
Showing 13 changed files with 142 additions and 81 deletions.
8 changes: 6 additions & 2 deletions docs/schema-avro.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,13 @@ You might want to split the Avro definition into several schemas one for each ty
}
```

To registry schemas with references they have to be registered in reverse order, so the referred schemas already exists. In this case B has to be registered before A. Furthermore A must define an array references to the referred schemas. A reference consist of a `name`, that should match the namespace + name, a schema `subject` and a schema `version`.
To register schemas with references, the schemas have to be registered in reverse order. The schema that references another schema has to be registered after the schema it references. In this example B has to be registered before A. Furthermore, when registering A, a list of references have to be provided. A reference consist of:

Notice the library will handle an arbitrary number of nested levels.
* `name` - the fully qualified name of the referenced schema. Example: `test.B`
* `subject` - the subject the schema is registered under in the registry
* `version` - the version of the schema you want to use

The library will handle an arbitrary number of nested levels.

```js
const schemaA = {
Expand Down
22 changes: 13 additions & 9 deletions docs/schema-json.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,45 @@ You might want to split the JSON definition into several schemas one for each ty

```JSON
{
"$id": "https://sumup.com/schemas/A",
"$id": "https://example.com/schemas/A",
"type": "object",
"properties": {
"id": { "type": "number" },
"b": { "$ref": "https://sumup.com/schemas/B" }
"b": { "$ref": "https://example.com/schemas/B" }
}
}
```

```JSON
{
"$id": "https://sumup.com/schemas/B",
"$id": "https://example.com/schemas/B",
"type": "object",
"properties": {
"id": { "type": "number" }
}
}
```

To registry schemas with references they have to be registered in reverse order, so the referred schemas already exists. In this case B has to be registered before A. Furthermore A must define an array references to the referred schemas. A reference consist of a `name`, that should match the $ref, a schema `subject` and a schema `version`.
To register schemas with references, the schemas have to be registered in reverse order. The schema that references another schema has to be registered after the schema it references. In this example B has to be registered before A. Furthermore, when registering A, a list of references have to be provided. A reference consist of:

Notice the library will handle an arbitrary number of nested levels.
* `name` - A URL matching the `$ref` from the schema
* `subject` - the subject the schema is registered under in the registry
* `version` - the version of the schema you want to use

The library will handle an arbitrary number of nested levels.

```js
const schemaA = {
$id: 'https://sumup.com/schemas/A',
$id: 'https://example.com/schemas/A',
type: 'object',
properties: {
id: { type: 'number' },
b: { $ref: 'https://sumup.com/schemas/B' },
b: { $ref: 'https://example.com/schemas/B' },
},
}

const schemaB = {
$id: 'https://sumup.com/schemas/B',
$id: 'https://example.com/schemas/B',
type: 'object',
properties: {
id: { type: 'number' },
Expand All @@ -65,7 +69,7 @@ const { id } = await schemaRegistry.register(
schema: JSON.stringify(schemaA),
references: [
{
name: 'https://sumup.com/schemas/B',
name: 'https://example.com/schemas/B',
subject: 'JSON:B',
version,
},
Expand Down
10 changes: 7 additions & 3 deletions docs/schema-protobuf.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ sidebar_label: Example Protobuf Schemas

## Schema with references to other schemas

You might want to split the Protobuf definition into several schemas one for each type.
You might want to split the Protobuf definition into several schemas, one for each type.

```protobuf
syntax = "proto3";
Expand All @@ -28,9 +28,13 @@ message B {
}
```

To registry schemas with references they have to be registered in reverse order, so the referred schemas already exists. In this case B has to be registered before A. Furthermore A must define an array references to the referred schemas. A reference consist of a `name`, that should match the import statement, a schema `subject` and a schema `version`.
To register schemas with references, the schemas have to be registered in reverse order. The schema that references another schema has to be registered after the schema it references. In this example B has to be registered before A. Furthermore, when registering A, a list of references have to be provided. A reference consist of:

Notice the library will handle an arbitrary number of nested levels.
* `name` - String matching the import statement. For example: `test/B.proto`
* `subject` - the subject the schema is registered under in the registry
* `version` - the version of the schema you want to use

The library will handle an arbitrary number of nested levels.

```js
const schemaA = `
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@kafkajs/confluent-schema-registry",
"version": "3.3.0",
"version": "3.2.1",
"main": "dist/index.js",
"description": "ConfluentSchemaRegistry is a library that makes it easier to interact with the Confluent schema registry, it provides convenient methods to encode, decode and register new schemas using the Apache Avro serialization format.",
"keywords": [
Expand Down
20 changes: 10 additions & 10 deletions src/@types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,21 +13,21 @@ export interface SchemaHelper {
getSubject(confluentSchema: ConfluentSchema, schema: Schema, separator: string): ConfluentSubject
toConfluentSchema(data: SchemaResponse): ConfluentSchema
updateOptionsFromSchemaReferences(
options: ProtocolOptions,
referredSchemas: ConfluentSchema[],
referencedSchemas: ConfluentSchema[],
options?: ProtocolOptions,
): ProtocolOptions
}

export type AvroOptions = Partial<ForSchemaOptions> & {
referredSchemas?: AvroConfluentSchema[]
referencedSchemas?: AvroConfluentSchema[]
}
export type JsonOptions = ConstructorParameters<typeof Ajv>[0] & {
ajvInstance?: {
compile: (schema: any) => ValidateFunction
}
referredSchemas?: JsonConfluentSchema[]
referencedSchemas?: JsonConfluentSchema[]
}
export type ProtoOptions = { messageName?: string; referredSchemas?: ProtoConfluentSchema[] }
export type ProtoOptions = { messageName?: string; referencedSchemas?: ProtoConfluentSchema[] }

export interface LegacyOptions {
forSchemaOptions?: AvroOptions
Expand Down Expand Up @@ -67,28 +67,28 @@ export interface ConfluentSubject {
export interface AvroConfluentSchema {
type: SchemaType.AVRO
schema: string | RawAvroSchema
references?: ReferenceType[]
references?: SchemaReference[]
}

export type ReferenceType = {
export type SchemaReference = {
name: string
subject: string
version: number
}
export interface ProtoConfluentSchema {
type: SchemaType.PROTOBUF
schema: string
references?: ReferenceType[]
references?: SchemaReference[]
}
export interface JsonConfluentSchema {
type: SchemaType.JSON
schema: string
references?: ReferenceType[]
references?: SchemaReference[]
}
export interface SchemaResponse {
schema: string
schemaType: string
references?: ReferenceType[]
references?: SchemaReference[]
}

export type ConfluentSchema = AvroConfluentSchema | ProtoConfluentSchema | JsonConfluentSchema
Expand Down
13 changes: 6 additions & 7 deletions src/AvroHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,12 @@ export default class AvroHelper implements SchemaHelper {
: this.getRawAvroSchema(schema)
// @ts-ignore TODO: Fix typings for Schema...

const addReferredSchemas = (userHook?: TypeHook): TypeHook => (
const addReferencedSchemas = (userHook?: TypeHook): TypeHook => (
schema: avro.Schema,
opts: ForSchemaOptions,
) => {
const avroOpts = opts as AvroOptions
avroOpts?.referredSchemas?.forEach(subSchema => {
avroOpts?.referencedSchemas?.forEach(subSchema => {
const rawSubSchema = this.getRawAvroSchema(subSchema)
avroOpts.typeHook = userHook
avro.Type.forSchema(rawSubSchema, avroOpts)
Expand All @@ -43,7 +43,7 @@ export default class AvroHelper implements SchemaHelper {

const avroSchema = avro.Type.forSchema(rawSchema, {
...opts,
typeHook: addReferredSchemas(opts?.typeHook),
typeHook: addReferencedSchemas(opts?.typeHook),
})

return avroSchema
Expand Down Expand Up @@ -83,10 +83,9 @@ export default class AvroHelper implements SchemaHelper {
}

updateOptionsFromSchemaReferences(
options: ProtocolOptions,
referredSchemas: AvroConfluentSchema[],
referencedSchemas: AvroConfluentSchema[],
options: ProtocolOptions = {},
): ProtocolOptions {
const opts = options ?? {}
return { ...opts, [SchemaType.AVRO]: { ...opts[SchemaType.AVRO], referredSchemas } }
return { ...options, [SchemaType.AVRO]: { ...options[SchemaType.AVRO], referencedSchemas } }
}
}
7 changes: 3 additions & 4 deletions src/JsonHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,9 @@ export default class JsonHelper implements SchemaHelper {
}

updateOptionsFromSchemaReferences(
options: ProtocolOptions,
referredSchemas: JsonConfluentSchema[],
referencedSchemas: JsonConfluentSchema[],
options: ProtocolOptions = {},
): ProtocolOptions {
const opts = options ?? {}
return { ...opts, [SchemaType.JSON]: { ...opts[SchemaType.JSON], referredSchemas } }
return { ...options, [SchemaType.JSON]: { ...options[SchemaType.JSON], referencedSchemas } }
}
}
6 changes: 3 additions & 3 deletions src/JsonSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@ export default class JsonSchema implements Schema {

private getJsonSchema(schema: JsonConfluentSchema, opts?: JsonOptions) {
const ajv = opts?.ajvInstance ?? new Ajv(opts)
const referredSchemas = opts?.referredSchemas
if (referredSchemas) {
referredSchemas.forEach(rawSchema => {
const referencedSchemas = opts?.referencedSchemas
if (referencedSchemas) {
referencedSchemas.forEach(rawSchema => {
const $schema = JSON.parse(rawSchema.schema)
// @ts-ignore
ajv.addSchema($schema, $schema['$id'])
Expand Down
10 changes: 6 additions & 4 deletions src/ProtoHelper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ export default class ProtoHelper implements SchemaHelper {
}

updateOptionsFromSchemaReferences(
options: ProtocolOptions,
referredSchemas: ProtoConfluentSchema[],
referencedSchemas: ProtoConfluentSchema[],
options: ProtocolOptions = {},
): ProtocolOptions {
const opts = options ?? {}
return { ...opts, [SchemaType.PROTOBUF]: { ...opts[SchemaType.PROTOBUF], referredSchemas } }
return {
...options,
[SchemaType.PROTOBUF]: { ...options[SchemaType.PROTOBUF], referencedSchemas },
}
}
}
6 changes: 3 additions & 3 deletions src/ProtoSchema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ export default class ProtoSchema implements Schema {
constructor(schema: ProtoConfluentSchema, opts?: ProtoOptions) {
const parsedMessage = protobuf.parse(schema.schema)
const root = parsedMessage.root
const referredSchemas = opts?.referredSchemas
const referencedSchemas = opts?.referencedSchemas

// handle all schema references independent on nested references
if (referredSchemas) {
referredSchemas.forEach(rawSchema => protobuf.parse(rawSchema.schema as string, root))
if (referencedSchemas) {
referencedSchemas.forEach(rawSchema => protobuf.parse(rawSchema.schema as string, root))
}

this.message = root.lookupType(this.getTypeName(parsedMessage, opts))
Expand Down
33 changes: 33 additions & 0 deletions src/SchemaRegistry.avro.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -509,6 +509,39 @@ describe('SchemaRegistry', () => {
;({ schema } = await schemaRegistry['_getSchema'](registeredSchema.id))
})

it('should be able to encode/decode enums schemas', async () => {
const obj = {
direction: Direction.UP,
attributes: { color: Color.BLUE },
}

const buffer = await schema.toBuffer(obj)
const resultObj = await schema.fromBuffer(buffer)

expect(resultObj).toEqual(obj)
})
})
describe('with enum typeHook defined as LegacyOptions', () => {
beforeEach(async () => {
const schemaRegistry = new SchemaRegistry(schemaRegistryArgs, {
forSchemaOptions: { typeHook },
})

await schemaRegistry.register(TestSchemas.EnumSchema, {
subject: 'Avro:EnumSchema',
})

const latest = apiResponse(await api.Subject.latestVersion({ subject: 'Avro:EnumSchema' }))
TestSchemas.EnumWithReferencesSchema.references[0].version = latest.version
const registeredSchema = await schemaRegistry.register(
TestSchemas.EnumWithReferencesSchema,
{
subject: 'Avro:EnumWithReferences',
},
)
;({ schema } = await schemaRegistry['_getSchema'](registeredSchema.id))
})

it('should be able to encode/decode enums schemas', async () => {
const obj = {
direction: Direction.UP,
Expand Down
Loading

0 comments on commit 3d2e0bb

Please sign in to comment.