Apicurio / apicurio-registry-client-sdk-js

Apicurio Registry client for JavaScript
Apache License 2.0
0 stars 3 forks source link

ArtifactsApi.createArtifact sends the wrong Content-Type for the documentation of what the body argument is supposed to be #32

Open Mainstay-Noah-Huppert opened 1 year ago

Mainstay-Noah-Huppert commented 1 year ago

I am trying to use the apicurio-registry-client javascript SDK client package. I am having issues using the ArtifactsApi.createArtifact() method to create an artifact. I believe that the SDK sends the wrong content type, resulting in the server expecting a URL to the schema instead of expecting the schema in the request body.

On the web UI when you create an artifact it sends a post request to /apis/registry/v2/groups/<group>/artifacts with the schema in its body. This request has the header Content-Type: application/json, and it works fine. However when you try to create an artifact with the javascript SDK ArtifactsApi.createArtifact() method it makes the same request, but with the Content-Type: application/create.extended+json.

It looks like the web UI intelligently sets the content type based on if it is creating the artifact from a URL or from data directly provided in the request: source code link. If creating from a URL the content type is set to application/create.extended+json, but if the schema is to be provided directly in the request body then it determines the MIME type of the data and sets the header to that.

Whereas the javascript SDK always sets the content type to application/create.extended+json no matter what: source code link.

This makes it so the ArtifactsApi.createArtifact() cannot be used according to how the doc comment on this method describes:

  • @param {any} body The content of the artifact being created. This is often, but not always, JSON data representing one of the supported artifact types: Avro (`AVRO`) Protobuf (`PROTOBUF`) JSON Schema (`JSON`) Kafka Connect (`KCONNECT`) OpenAPI (`OPENAPI`) AsyncAPI (`ASYNCAPI`) GraphQL (`GRAPHQL`) Web Services Description Language (`WSDL`) * XML Schema (`XSD`)
Mainstay-Noah-Huppert commented 1 year ago

I ended up making a custom API client just for this create artifact call:

async function createArtifact(
    group: string, id: string, schemaType: string, schema: string, upsert: boolean
): Promise<any> {
  const queryString: { [key: string]: string | boolean } = {};
  if (upsert) {
    queryString["ifExists"] = "UPDATE";
    queryString["canonical"] = true;
  }

  const url = `/groups/${encodeURIComponent(group)}/artifacts`;

  const reqOpts = {
    params: queryString,
    headers: {
      "Content-Type": "application/json",
      "X-Registry-ArtifactType": schemaType,
      "X-Registry-ArtifactId": id,
    },
  };

    const res = await axiosClient.post(url, schema, reqOpts);
    return res.data;
};

Make sure you setup an axiosClient variable with the base URL of your server configured.

Later I took this base and decoded the result using io-ts and fp-ts based on the Apicurio registry - Artifacts - Create Artifact API description, but the above code is the most generic to allow any code base to handle decoding however they might like.