Go Middleware Plugin impacted in 5.2.x. no apiDefinition in request for OAS api

release-5.2.5/OSS/5.2.5

** problem ***
Following the TT-8515 update, a breaking change has been introduced across all middleware. As a result of this evolution, the go middleware plugin no longer receives the apiDefinition but the OASdefinition if it is OAS only. However, the apiDefinition serves as a common link for all APIs, OAS or not. This is a significant change that affects middleware, especially those that rely on configData.

In addition to having to conduct additional tests to ensure the plugin can retrieve the configData regardless of the API type (OAS or not), this requires me to redeploy all APIs. This is necessary to place the ConfigData in the OAS instead of the Tyk spec. For a minor version update, this has a significant impact on existing setups.

Here is the code responsible for the breaking change (mw_go_plugin.go):

In v 5.0:
…
ctx.SetDefinition(r, m.Spec.APIDefinition)
…

In v 5.2.5:
…
// Inject definition into request context:
if m.Spec.IsOAS {
setOASDefinition(r, &m.Spec.OAS)
} else {
ctx.SetDefinition(r, m.Spec.APIDefinition)
}

Expected behaviour
I think it"s possible to setDefinition + setOASDefinition

@Alexandre_Wintrebert Thanks for raising your concern. I think this is a design question that @Andy_O might be able to respond to.

The change you observed was added in v5.2.0. We introduce changes like this in early access or minor releases e.g. v3.2 GraphQL schema for Tyk API definitions

I do need to point out that 5.1.x and 5.2.x are early access/minor releases that include new or enhanced features. Hence they could change existing functionality or cause backward incompatibility issues that result in breaking changes. For non-breaking changes, we recommend sticking with LTS releases

Hi @Alexandre_Wintrebert,

When working with Tyk OAS APIs, you will work with the Tyk OAS API Definition. This comprises the OpenAPI Document (OAS description of your API) plus the Tyk vendor extension (which is all encapsulated in the x-tyk-api-gateway object). This is an alternative to and replaces the legacy Tyk Classic API Definition.

Tyk OAS is currently in Early Access meaning that we have not yet reached a stage where we are confident that all features configurable via the Tyk Classic API Definition are also supported by the Tyk OAS API definition.

You are correct that in Tyk 5.2.0 we added the facility to pass custom attributes (config data) into Go Plugins for Tyk OAS APIs.

You do this by adding pluginConfig to the global section of x-tyk-api-gateway in your API Definition, for example:

      "global": {
        "pluginConfig": {
          "data": {
            "enabled": true,
            "value": {
              "my-data": "123"
            }
          }
        }

You do not need access to the legacy Tyk Classic API Definition if you are using Tyk OAS.

I hope this helps to unblock you.

If not, then please can you elaborate and provide your Tyk OAS API Definition and plugin so that we can better understand your issue?

Thanks.

Hello,
As indicated in the documentation, the TYK definition is the pivotal definition for any API exposed on the gateway. Right, no ?
However, instead of placing user data in the definition during the import of an OAS, you have chosen to differentiate it during the API call execution. This is unfortunate because it introduces a conditional “if” concept in the plugins that work at the level of the simple TYK definition. Your evolution makes the TYK definition insufficient, especially in my case where plugins work exactly the same way, whether it’s an OAS or a simple REST proxy. It’s a pity, and I believe it’s a mistake, but that’s just my opinion. I have adapted to this change on my end; I had to add an additional “if” statement in my plugins to ensure the retrieval of userData:

Extract of my plugin:
(V5.0.0)
func GetConfigData(r *http.Request) (map[string]interface{}, error) {
apiDef := ctx.GetDefinition(r)
if apiDef == nil || apiDef.ConfigData == nil {
return nil, fmt.Errorf(“Cannot retreive ConfigData from definition”)
}
return apiDef.ConfigData, nil
}

(V5.2.5)
func GetConfigData(r *http.Request) (map[string]interface{}, error) {
oasDef := ctx.GetOASDefinition(r)
if oasDef != nil {
mdw := oasDef.GetTykMiddleware()
if mdw == nil ||
mdw.Global == nil ||
mdw.Global.PluginConfig == nil ||
mdw.Global.PluginConfig.Data == nil ||
mdw.Global.PluginConfig.Data.Value == nil {
return nil, fmt.Errorf(“Cannot retreive ConfigData from API definition”)
}
return mdw.Global.PluginConfig.Data.Value, nil
} else {
apiDef := ctx.GetDefinition(r)
if apiDef == nil || apiDef.ConfigData == nil {
return nil, fmt.Errorf(“Cannot retreive ConfigData from API Definition”)
}
return apiDef.ConfigData, nil
}
}

Thanks

1 Like

Hi @Alexandre_Wintrebert,

Firstly I’m glad it sounds like you’re now unblocked and able to progress.

Tyk OAS is different because we allow you to work with your OAS compliant API document/definition natively - you can create it outside Tyk, import it, update it externally and update your API on Tyk, re-export… and it stays a coherent OpenAPI object. All of the Tyk vendor-specific data is stored in an extension, x-tyk-api-gateway. Not only does this support you to keep your OpenAPI document as a source of truth that you can manage outside Tyk, but the approach we have taken minimises the size and complexity of the API definition.

Tyk Classic is an entirely vendor-specific API definition and, due to the way it has evolved over the past 6+ years, is neither small nor simple to navigate.

An API deployed on Tyk has only one definition file: Tyk OAS or Tyk Classic. Our intention is to encourage adoption of Tyk OAS, once it moves out of Early Access, and ultimately for this to replace the legacy approach.

For your plugin, I can understand the frustration of trying to make it work with both Tyk Classic and Tyk OAS APIs, but if you are only using one style then your plugin needs only to support the appropriate method of accessing context variables for that style of API.

I hope this explanation helps to explain the situation more clearly.

Thanks.