Skip to content

Merging to release-5.9: [TT-15505] Remove negate field as mandatory from the OAS API schema (#7284) #7286

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conversation

buger
Copy link
Member

@buger buger commented Aug 8, 2025

User description

TT-15505 Remove negate field as mandatory from the OAS API schema (#7284)

User description

TT-15505
Summary Fix URL Rewrite Middleware Schema breaking change introduced in 5.8.3 and 5.9.0
Type Bug Bug
Status In Dev
Points N/A
Labels jira_escalated

Description

Make negate field optional in URL rewrite schema

The negate field was previously made mandatory in the OAS API schema,
which broke existing API definitions that don't have the negate field
defined. This prevented customers from updating their APIs.

This change:

  • Removes negate from required fields in both OAS schema files
  • Adds omitempty tags to the URLRewriteRule struct to handle optional
    negate field
  • Restores backward compatibility with existing API definitions

Fixes breaking change introduced in previous release where customers
with API definitions lacking negate field could not update their APIs.

Related Issue

Motivation and Context

How This Has Been Tested

Screenshots (if appropriate)

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing
    functionality to change)
  • Refactoring or add test (improvements in base code or adds test
    coverage to functionality)

Checklist

  • I ensured that the documentation is up to date
  • I explained why this PR updates go.mod in detail with reasoning
    why it's required
  • I would like a code coverage CI quality gate exception and have
    explained why

PR Type

Bug fix, Enhancement


Description

  • Make negate field optional in URL rewrite schema

  • Remove negate from required fields in OAS schema files

  • Add omitempty to Negate in URLRewriteRule struct

  • Restore backward compatibility for existing API definitions


Diagram Walkthrough

flowchart LR
  schemaOld["OAS Schema: 'negate' required"] -- "remove from required" --> schemaNew["OAS Schema: 'negate' optional"]
  structOld["Go Struct: 'negate' mandatory"] -- "add omitempty" --> structNew["Go Struct: 'negate' optional"]
  schemaNew -- "restores compatibility" --> compatibility["Backward Compatibility"]
Loading

File Walkthrough

Relevant files
Enhancement
url_rewrite.go
Make `Negate` field optional in Go struct                               

apidef/oas/url_rewrite.go

  • Add omitempty to Negate field in URLRewriteRule struct
  • Make Negate optional in Go struct serialization
+1/-1     
Bug fix
x-tyk-api-gateway.json
Remove `negate` from required fields in OAS schema             

apidef/oas/schema/x-tyk-api-gateway.json

  • Remove negate from required fields in two schema definitions
  • Make negate field optional in OAS schema
+2/-4     
x-tyk-api-gateway.strict.json
Remove `negate` from required fields in strict OAS schema

apidef/oas/schema/x-tyk-api-gateway.strict.json

  • Remove negate from required fields in two strict schema definitions
  • Make negate field optional in strict OAS schema
+2/-4     


Co-authored-by: Claude [email protected]


PR Type

Bug fix, Enhancement


Description

  • Make URL rewrite negate optional

  • Remove negate from OAS required fields

  • Add omitempty to Go struct field

  • Update tests to cover absent negate


Diagram Walkthrough

flowchart LR
  schemaOld["OAS schemas require 'negate'"] -- "remove from required" --> schemaNew["OAS: 'negate' optional"]
  goOld["Go URLRewriteRule without omitempty"] -- "add omitempty" --> goNew["Go: 'negate' omitted when unset"]
  testsOld["Tests lacking no-negate cases"] -- "add examples" --> testsNew["Testdata includes rules without 'negate'"]
  schemaNew -- "unblocks updates" --> compat["Backward compatibility restored"]
  goNew -- "serializes correctly" --> compat
Loading

File Walkthrough

Relevant files
Enhancement
url_rewrite.go
Make Negate optional in URLRewriteRule struct                       

apidef/oas/url_rewrite.go

  • Add omitempty to Negate JSON/BSON tags
  • Make Negate optional in serialization
+1/-1     
Bug fix
x-tyk-api-gateway.json
Relax OAS schema: negate no longer required                           

apidef/oas/schema/x-tyk-api-gateway.json

  • Remove negate from required arrays
  • Keep negate property as boolean, optional
+2/-4     
x-tyk-api-gateway.strict.json
Relax strict OAS schema: optional negate                                 

apidef/oas/schema/x-tyk-api-gateway.strict.json

  • Remove negate from strict schema required
  • Preserve property definition; make optional
+2/-4     
Tests
urlRewrite-native.json
Testdata: header rule without negate flag                               

apidef/oas/testdata/urlRewrite-native.json

  • Add header match case without negate
  • Ensure coverage for default negate behavior
+4/-0     
urlRewrite-oas.json
Testdata: OAS rule without negate property                             

apidef/oas/testdata/urlRewrite-oas.json

  • Add URL rewrite rule lacking negate
  • Validate schema accepts omitted negate
+5/-0     

…#7284)

### **User description**
<details open>
<summary><a href="https://tyktech.atlassian.net/browse/TT-15505"
title="TT-15505" target="_blank">TT-15505</a></summary>
  <br />
  <table>
    <tr>
      <th>Summary</th>
<td>Fix URL Rewrite Middleware Schema breaking change introduced in
5.8.3 and 5.9.0</td>
    </tr>
    <tr>
      <th>Type</th>
      <td>
<img alt="Bug"
src="https://tyktech.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10303?size=medium"
/>
        Bug
      </td>
    </tr>
    <tr>
      <th>Status</th>
      <td>In Dev</td>
    </tr>
    <tr>
      <th>Points</th>
      <td>N/A</td>
    </tr>
    <tr>
      <th>Labels</th>
<td><a
href="https://tyktech.atlassian.net/issues?jql=project%20%3D%20TT%20AND%20labels%20%3D%20jira_escalated%20ORDER%20BY%20created%20DESC"
title="jira_escalated">jira_escalated</a></td>
    </tr>
  </table>
</details>
<!--
  do not remove this marker as it will break jira-lint's functionality.
  added_by_jira_lint
-->

---

<!-- Provide a general summary of your changes in the Title above -->

## Description

Make negate field optional in URL rewrite schema

The negate field was previously made mandatory in the OAS API schema,
which broke existing API definitions that don't have the negate field
defined. This prevented customers from updating their APIs.

This change:
  - Removes negate from required fields in both OAS schema files
  - Adds omitempty tags to the URLRewriteRule struct to handle optional
  negate field
  - Restores backward compatibility with existing API definitions

Fixes breaking change introduced in previous release where customers
with API definitions lacking negate field could not update their APIs.

## Related Issue

<!-- This project only accepts pull requests related to open issues. -->
<!-- If suggesting a new feature or change, please discuss it in an
issue first. -->
<!-- If fixing a bug, there should be an issue describing it with steps
to reproduce. -->
<!-- OSS: Please link to the issue here. Tyk: please create/link the
JIRA ticket. -->

## Motivation and Context

<!-- Why is this change required? What problem does it solve? -->

## How This Has Been Tested

<!-- Please describe in detail how you tested your changes -->
<!-- Include details of your testing environment, and the tests -->
<!-- you ran to see how your change affects other areas of the code,
etc. -->
<!-- This information is helpful for reviewers and QA. -->

## Screenshots (if appropriate)

## Types of changes

<!-- What types of changes does your code introduce? Put an `x` in all
the boxes that apply: -->

- [x] Bug fix (non-breaking change which fixes an issue)
- [ ] New feature (non-breaking change which adds functionality)
- [x] Breaking change (fix or feature that would cause existing
functionality to change)
- [ ] Refactoring or add test (improvements in base code or adds test
coverage to functionality)

## Checklist

<!-- Go over all the following points, and put an `x` in all the boxes
that apply -->
<!-- If there are no documentation updates required, mark the item as
checked. -->
<!-- Raise up any additional concerns not covered by the checklist. -->

- [ ] I ensured that the documentation is up to date
- [ ] I explained why this PR updates go.mod in detail with reasoning
why it's required
- [ ] I would like a code coverage CI quality gate exception and have
explained why


___

### **PR Type**
Bug fix, Enhancement


___

### **Description**
- Make `negate` field optional in URL rewrite schema

- Remove `negate` from required fields in OAS schema files

- Add `omitempty` to `Negate` in `URLRewriteRule` struct

- Restore backward compatibility for existing API definitions


___

### Diagram Walkthrough


```mermaid
flowchart LR
  schemaOld["OAS Schema: 'negate' required"] -- "remove from required" --> schemaNew["OAS Schema: 'negate' optional"]
  structOld["Go Struct: 'negate' mandatory"] -- "add omitempty" --> structNew["Go Struct: 'negate' optional"]
  schemaNew -- "restores compatibility" --> compatibility["Backward Compatibility"]
```



<details> <summary><h3> File Walkthrough</h3></summary>

<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>url_rewrite.go</strong><dd><code>Make `Negate` field
optional in Go struct</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></summary>
<hr>

apidef/oas/url_rewrite.go

<ul><li>Add <code>omitempty</code> to <code>Negate</code> field in
<code>URLRewriteRule</code> struct<br> <li> Make <code>Negate</code>
optional in Go struct serialization</ul>


</details>


  </td>
<td><a
href="https://github.com/TykTechnologies/tyk/pull/7284/files#diff-7317c6061fb6488e079d733230045c7cbc1b4b2ffb98bb7da20d4025f4976e51">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr><tr><td><strong>Bug fix</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>x-tyk-api-gateway.json</strong><dd><code>Remove
`negate` from required fields in OAS schema</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

apidef/oas/schema/x-tyk-api-gateway.json

<ul><li>Remove <code>negate</code> from required fields in two schema
definitions<br> <li> Make <code>negate</code> field optional in OAS
schema</ul>


</details>


  </td>
<td><a
href="https://github.com/TykTechnologies/tyk/pull/7284/files#diff-78828969c0c04cc1a776dfc93a8bad3c499a8c83e6169f83e96d090bed3e7dd0">+2/-4</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>x-tyk-api-gateway.strict.json</strong><dd><code>Remove
`negate` from required fields in strict OAS schema</code></dd></summary>
<hr>

apidef/oas/schema/x-tyk-api-gateway.strict.json

<ul><li>Remove <code>negate</code> from required fields in two strict
schema definitions<br> <li> Make <code>negate</code> field optional in
strict OAS schema</ul>


</details>


  </td>
<td><a
href="https://github.com/TykTechnologies/tyk/pull/7284/files#diff-39a62344d6b741814a58dfd2d219665ecdf962bbec8e755dbc61e1684bb4892a">+2/-4</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></td></tr></tr></tbody></table>

</details>

___

---------

Co-authored-by: Claude <[email protected]>

(cherry picked from commit 35b0c98)
Copy link
Contributor

github-actions bot commented Aug 8, 2025

API Changes

--- prev.txt	2025-08-08 08:02:38.996966994 +0000
+++ current.txt	2025-08-08 08:02:29.803034287 +0000
@@ -4746,7 +4746,7 @@
 
 	// Negate is a boolean negation operator. Setting it to true inverts the matching behaviour
 	// such that the rewrite will be triggered if the value does not match the `pattern` for this rule.
-	Negate bool `bson:"negate" json:"negate"`
+	Negate bool `bson:"negate,omitempty" json:"negate,omitempty"`
 }
     URLRewriteRule represents a rewrite
     matching rules. Tyk classic API definition:

Copy link
Contributor

github-actions bot commented Aug 8, 2025

PR Code Suggestions ✨

Explore these optional code suggestions:

CategorySuggestion                                                                                                                                    Impact
Possible issue
Preserve unset vs explicit false

Making negate optional changes its zero-value default to false when omitted. Verify
that downstream logic differentiates between "explicit false" and "unset" if needed.
If semantics differ, switch to a pointer to detect absence and preserve backward
compatibility for existing behavior.

apidef/oas/url_rewrite.go [119]

-Negate bool `bson:"negate,omitempty" json:"negate,omitempty"`
+Negate *bool `bson:"negate,omitempty" json:"negate,omitempty"`
Suggestion importance[1-10]: 6

__

Why: The suggestion correctly highlights a potential semantic change by making negate optional; using *bool would allow distinguishing unset from false, which might be important. However, it asks to verify behavior and proposes a structural change with potential ripple effects, so impact is moderate.

Low
Allow optional negate in strict

Since negate is no longer required, allow it to be absent without failing validation
in strict mode by marking it nullable. This prevents strict validation from
rejecting objects that omit negate.

apidef/oas/schema/x-tyk-api-gateway.strict.json [956-958]

 "negate": {
-  "type": "boolean"
+  "type": ["boolean", "null"]
 }
Suggestion importance[1-10]: 3

__

Why: Making the property nullable is not necessary for optionality in JSON Schema; absence is already allowed when not required. Allowing null could loosen validation beyond intent, so the recommendation has limited benefit.

Low
General
Accept null for optional negate

Align the non-strict schema with the optional nature of negate by permitting null,
ensuring tools that default missing optionals to null pass validation. This avoids
accidental schema validation failures for generated specs.

apidef/oas/schema/x-tyk-api-gateway.json [944-946]

 "negate": {
-  "type": "boolean"
+  "type": ["boolean", "null"]
 }
Suggestion importance[1-10]: 3

__

Why: Similar to the strict schema, optional fields need not be nullable to be omitted; expanding the type to include null may not align with desired schema constraints, yielding minor value.

Low

Copy link
Contributor

github-actions bot commented Aug 8, 2025

Code Review: PR #7286 - Remove negate field as mandatory from the OAS API schema

Overview

This PR addresses a breaking change introduced in versions 5.8.3 and 5.9.0 that made the negate field mandatory in URL rewrite rules. This change broke backward compatibility with existing API definitions that didn't have the negate field defined, preventing customers from updating their APIs.

Changes

The PR makes three key changes:

  1. Go Struct Change: Adds omitempty tag to the Negate field in the URLRewriteRule struct

    // Before
    Negate bool `bson:"negate" json:"negate"`
    
    // After
    Negate bool `bson:"negate,omitempty" json:"negate,omitempty"`
  2. OAS Schema Changes: Removes negate from required fields in both schema files:

    • apidef/oas/schema/x-tyk-api-gateway.json
    • apidef/oas/schema/x-tyk-api-gateway.strict.json
  3. Test Data Validation: The test data already includes examples of URL rewrite rules both with and without the negate field:

    • In urlRewrite-oas.json, some rules include negate: true/false while others omit it entirely
    • In urlRewrite-native.json, the classic API format uses reverse: true/false which maps to negate

Analysis

Positive Aspects

  • Restores Backward Compatibility: Makes the negate field optional, allowing existing API definitions without this field to be processed correctly
  • Minimal Change: The PR makes focused changes to only the necessary files
  • Consistent Implementation: The change is applied consistently across both the Go struct and the OAS schema definitions
  • Documentation: The field's behavior is well-documented in the code comments
  • Test Coverage: The test data includes examples of rules both with and without the negate field

Potential Considerations

  • ⚠️ Default Behavior: When negate is omitted, it will default to false (Go's zero value for bool). This appears to be the expected behavior since the field is used to invert matching behavior, and the default should be non-inverted.
  • ⚠️ Serialization/Deserialization: The omitempty tag means the field won't be included in JSON/BSON output when it's false, which could affect systems that explicitly check for the presence of the field rather than its value.

Implementation Details

The implementation correctly addresses the issue:

  1. In the Go struct, adding omitempty ensures that when the field has its zero value (false), it won't be included in JSON/BSON serialization.

  2. In the OAS schema files, removing negate from the required arrays makes the field optional while maintaining its type definition.

  3. The code that handles the conversion between the OAS representation and the classic API definition (appendRules and extractTriggerOptions methods) properly handles the field regardless of whether it's present or not.

  4. The test data demonstrates that the system can handle both cases - rules with explicit negate: true/false and rules where the field is omitted (implying negate: false).

Conclusion

This PR correctly addresses the breaking change by making the negate field optional in both the Go struct and OAS schema definitions. The changes are minimal and focused on restoring backward compatibility without introducing new issues.

The PR should be approved as it fixes a critical issue affecting customer API updates. The fix properly restores backward compatibility while maintaining the functionality for API definitions that do specify the negate field.


Tip: Mention me again using /probe <request>.
Powered by Probe AI

Copy link

sonarqubecloud bot commented Aug 8, 2025

@lghiur lghiur merged commit 2f81b10 into release-5.9 Aug 8, 2025
38 of 39 checks passed
@lghiur lghiur deleted the merge/release-5.9/35b0c9834624714f20343aebbca348e8dd4e7e77 branch August 8, 2025 09:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants