Xero-OpenAPI icon indicating copy to clipboard operation
Xero-OpenAPI copied to clipboard

Unable to build Go SDK from OpenAPI (failures in accounting schema)

Open 17twenty opened this issue 2 years ago • 4 comments

Uh Oh - no matter the tools, we're unable to generate a buildable SDK for Golang using the Xero OpenAPI schema. The previous SDK is deprecated and we're looking to accelerate our development using the official tooling from Xero.

Is there a known working process you guys are able to share that outlines the process, i've worked in the space for a while and this is the first time that all tools seem to be unable to parse spec files and give something buildable 😬

Expected Behavior

Ability to build a working Golang SDK/client from the in-repo schema

Current Behavior

When building with either the recommended tool - https://github.com/OpenAPITools/openapi-generator or the popular tool oapi-codegen from https://github.com/deepmap/oapi-codegen - many issues arise due to the way that the schema has been structured.

The below is one example trying to validate the schema using a common tool.

go run github.com/getkin/kin-openapi/cmd/validate@latest -- xero_accounting.yaml 
2023/06/23 11:59:11 Loading error: kin-openapi bug found: circular schema reference not handled - #/components/schemas/Payment -> #/components/schemas/CreditNote -> #/components/schemas/Allocation -> #/components/schemas/CreditNote -> #/components/schemas/Payment -> #/components/schemas/Invoice -> #/components/schemas/Prepayment -> #/components/schemas/Allocation -> #/components/schemas/Invoice -> #/components/schemas/Overpayment -> #/components/schemas/Payment -> #/components/schemas/Overpayment -> #/components/schemas/Allocation -> #/components/schemas/Prepayment -> #/components/schemas/Payment
exit status 1

Possible Solution

I wrote a script to contribute that i'll paste below that can go some way to generating the required SDK - including commented out ability to switch generators as needed:

#!/usr/bin/env bash

# Depending on choice, either:
# brew install openapi-generator
# or 
# go install github.com/deepmap/oapi-codegen/cmd/oapi-codegen@latest

PACKAGE_NAME=xero
[ -d "$PACKAGE_NAME" ] || mkdir -p "$PACKAGE_NAME"
rm -rf "$PACKAGE_NAME"/

for FILE in *.yaml; do 
    # echo $FILE;
    ORIGINAL_STRIPPED=$(basename $FILE .yaml);
    # Normalise lower case/hyphens
    NEW=$(echo $ORIGINAL_STRIPPED | tr 'xero-' 'xero_' | sed 's/xero_//')
    # Generate the API spec
    echo Generating from "$ORIGINAL_STRIPPED"
    mkdir -p "$PACKAGE_NAME/$NEW/"
    oapi-codegen --package=main -generate=types,client  -package "$PACKAGE_NAME" "$FILE" > "$PACKAGE_NAME/$NEW".gen.go
    # openapi-generator generate -i "$FILE" -g go --additional-properties packageName="$NEW" -o ./"$PACKAGE_NAME/$NEW/" 
done

However these result in duplicate values in packages, unresolvable references or bad type definitions.

Context

We are currently building a financial services integration and would like to be able to use Xero as an approved accounting platform.

Your Environment

  • Version used: main
  • Browser Name and version: Chrome or Safari - any
  • Operating System and version (desktop or mobile): MacOSX
  • Link to your project: n/a at this time.

17twenty avatar Jun 23 '23 02:06 17twenty

PETOSS-307

github-actions[bot] avatar Jun 23 '23 02:06 github-actions[bot]

Thanks for raising an issue, a ticket has been created to track your request

github-actions[bot] avatar Jun 23 '23 02:06 github-actions[bot]

In addition, after taking advice - I tried using redoc to reformat the YAML before parsing but that gets sad too:

$ redocly bundle --dereferenced  xero_accounting.yaml > new.yaml
bundling xero_accounting.yaml...
📦 Created a bundle for xero_accounting.yaml at stdout 267ms. 
$ go run github.com/getkin/kin-openapi/cmd/validate@latest -- new.yaml 
2023/06/23 11:56:27 error converting YAML to JSON: yaml: anchor 'ref_20' value contains itself
exit status 1

17twenty avatar Jun 23 '23 02:06 17twenty

After the linked issue was solved I was able to generate types using oapi-codegen:

# install v2.0
$ go install github.com/deepmap/oapi-codegen/v2/cmd/[email protected]

# create config.yaml with circular reference limit (potentially can lower)
$ cat ./config.yaml 
package: xero
generate:
  models: true
compatibility:
  circular-reference-limit: 10

# generate 
$ oapi-codegen -config ./config.yaml xero_accounting.yaml > accounting.go

accounting.go:

$ head -n 30 accounting.go
// Package xero provides primitives to interact with the openapi HTTP API.
//
// Code generated by github.com/deepmap/oapi-codegen/v2 version v2.0.0 DO NOT EDIT.
package xero

import (
	"bytes"
// snip

	"github.com/oapi-codegen/runtime"
	openapi_types "github.com/oapi-codegen/runtime/types"
)

const (
	OAuth2Scopes = "OAuth2.Scopes"
)

// Defines values for AccountBankAccountType.
const (
	AccountBankAccountTypeBANK       AccountBankAccountType = "BANK"
	AccountBankAccountTypeCREDITCARD AccountBankAccountType = "CREDITCARD"
	AccountBankAccountTypeEmpty      AccountBankAccountType = ""
	AccountBankAccountTypeNONE       AccountBankAccountType = "NONE"

karlskewes avatar Dec 10 '23 01:12 karlskewes