Skip to content

Anonymous schemas should have meaningful ids #176

@jonaslagoni

Description

@jonaslagoni

Reason/Context

We at Eurisco are not a big fan of the anonymous schema ids. They don't give any context to what anonymous schema or properties they are apart of which makes it hard to track down where it belongs. Instead we replace any anonymous schema ids to be the path to the object, see example solution for more details.

Description

The function giving schemas and messages anonymous ids need to be changed to another algorithm.

This will be breaking change in the regard anonymous schema ids are no longer present and people have to update their implementations unless they manually defined all schemas.

Example solution

My colleague developed a custom hook for changing the anonymous schema ids recursively by saving the path to that schema.

module.exports = {
    'generate:before': async generator => {
        preprocess(generator, generator.asyncapi)
    }
};

preprocess = (generator, obj, lastKey = "", lastSchemaID = "") => {
    // Fix anonymous x-parser-schema-id
    const schemaId = obj["x-parser-schema-id"]
    if (schemaId !== undefined) {
        if (schemaId.startsWith("<anonymous-schema-")) {
            const newSchemaId = lowerFirst(lastSchemaID + upperFirst(lastKey))
            obj["x-parser-schema-id"] = newSchemaId
            lastSchemaID = newSchemaId
        } else {
            lastSchemaID = schemaId
        }
    }
    const keys = Object.keys(obj)
    for (let i = 0; i < keys.length; i++) { 
        let key = keys[i]
        const value = obj[key];
        if (typeof value === 'object' && value != undefined) {
            let newKey = key
            if (key == "payload" && obj["name"] !== undefined && lastKey === "message") {
                lastSchemaID = obj["name"]
            } else if (key == "items" && obj["type"] === "array") {
                newKey = ""
            }
            if(!!obj['x-parser-circular-props']){
                continue;
            }
            preprocess(generator, value, newKey, lastSchemaID);
        }
    }
    return obj
}
upperFirst = (str) => {
    return str.charAt(0).toUpperCase() + str.slice(1);
};
lowerFirst = (str) => {
    return str.charAt(0).toLowerCase() + str.slice(1);
};

together with the hook and the following AsyncAPI document

asyncapi: '2.0.0'
info:
  title: Questionaire
  version: '1.0.0'
defaultContentType: application/json
channels:
  questionaire/get:
    description: "Get the newest version of the questionaires"
    publish:
      message:
        name: questionaire
        payload:
            type: object 
            x-parser-schema-id: questionaire
            properties:
                steps: 
                    type: object
                    additionalProperties: 
                        type: string

It would normally give the inner property steps of questionaire the id <anonymous-schema-x> but with the hook it will get questionaireSteps.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions