A diff tool for OpenAPI Spec 3.
- Generate a diff report in YAML, Text/Markdown or HTML
- Run from Docker
- Embed in your go program
- Compare files from the file system or over http/s
- Compare specs in YAML or JSON format
- Comprehensive diff including all aspects of OpenAPI Specification: paths, operations, parameters, request bodies, responses, schemas, enums, callbacks, security etc.
- Detect breaking changes (Beta feature. Please report issues)
git clone https://github.com/Tufin/oasdiff.git
cd oasdiff
go build
./oasdiff -base data/openapi-test1.yaml -revision data/openapi-test2.yaml
docker run --rm -t tufin/oasdiff -format text -base https://raw.githubusercontent.com/Tufin/oasdiff/main/data/openapi-test1.yaml -revision https://raw.githubusercontent.com/Tufin/oasdiff/main/data/openapi-test3.yaml
Text and markdown output provide only a subset of the full diff. To see the full diff, use the default format: YAML.
docker run --rm -t tufin/oasdiff -format html -base https://raw.githubusercontent.com/Tufin/oasdiff/main/data/openapi-test1.yaml -revision https://raw.githubusercontent.com/Tufin/oasdiff/main/data/openapi-test3.yaml
HTML output provides only a subset of the full diff. To see the full diff, use the default format: YAML.
docker run --rm -t tufin/oasdiff -format yaml -base https://raw.githubusercontent.com/Tufin/oasdiff/main/data/openapi-test1.yaml -revision https://raw.githubusercontent.com/Tufin/oasdiff/main/data/openapi-test3.yaml
This is the default output format.
Note that no output means an empty diff (no changes).
docker run --rm -t tufin/oasdiff -format yaml -base https://raw.githubusercontent.com/Tufin/oasdiff/main/data/openapi-test1.yaml -revision https://raw.githubusercontent.com/Tufin/oasdiff/main/data/openapi-test3.yaml --breaking-only
docker run --rm -t -v $(pwd)/data:/data:ro tufin/oasdiff -base /data/openapi-test1.yaml -revision /data/openapi-test3.yaml
Replace $(pwd)/data
by the path that contains your files.
Add the -format
flag to generate other formats (text or html).
docker run --rm -t tufin/oasdiff -help
./oasdiff -base data/openapi-test1.yaml -revision data/openapi-test5.yaml -format text
POST /register POST /subscribe
GET /api/{domain}/{project}/badges/security-score
- Modified query param: filter
- Content changed
- Modified media type: application/json
- Schema changed
- Required changed
- Schema changed
- Modified media type: application/json
- Content changed
- Modified query param: image
- Modified query param: token
- Schema changed
- MaxLength changed from 29 to
- Schema changed
- Modified header param: user
- Schema changed
- Schema added
- Content changed
- Deleted media type: application/json
- Schema changed
- Modified cookie param: test
- Content changed
- Modified media type: application/json
- Schema changed
- Type changed from 'object' to 'string'
- Schema changed
- Modified media type: application/json
- Content changed
- Responses changed
- New response: default
- Deleted response: 200
- Modified response: 201
- Content changed
- Modified media type: application/xml
- Schema changed
- Type changed from 'string' to 'object'
- Schema changed
- Modified media type: application/xml
- Content changed
GET /api/{domain}/{project}/install-command
- Deleted header param: network-policies
- Responses changed
- Modified response: default
- Description changed from 'Tufin1' to 'Tufin'
- Headers changed
- Deleted header: X-RateLimit-Limit
- Modified response: default
./oasdiff -base data/openapi-test1.yaml -revision data/openapi-test5.yaml -format yaml
info:
title:
from: Tufin
to: Tufin1
contact:
added: true
license:
added: true
version:
from: 1.0.0
to: 1.0.1
paths:
deleted:
- /register
- /subscribe
modified:
/api/{domain}/{project}/badges/security-score:
operations:
modified:
GET:
tags:
deleted:
- security
parameters:
modified:
cookie:
test:
content:
mediaTypeModified:
application/json:
schema:
type:
from: object
to: string
header:
user:
schema:
schemaAdded: true
content:
mediaTypeDeleted:
- application/json
query:
filter:
content:
mediaTypeModified:
application/json:
schema:
required:
stringsdiff:
added:
- type
image:
examples:
deleted:
- "0"
token:
schema:
maxLength:
from: 29
to: null
responses:
added:
- default
deleted:
- "200"
modified:
"201":
content:
mediaTypeModified:
application/xml:
schema:
type:
from: string
to: object
parameters:
deleted:
path:
- domain
/api/{domain}/{project}/install-command:
operations:
modified:
GET:
parameters:
deleted:
header:
- network-policies
responses:
modified:
default:
description:
from: Tufin1
to: Tufin
headers:
deleted:
- X-RateLimit-Limit
servers:
added:
- https://www.tufin.io/securecloud
endpoints:
deleted:
- method: POST
path: /register
- method: POST
path: /subscribe
modified:
? method: GET
path: /api/{domain}/{project}/badges/security-score
: tags:
deleted:
- security
parameters:
modified:
cookie:
test:
content:
mediaTypeModified:
application/json:
schema:
type:
from: object
to: string
header:
user:
schema:
schemaAdded: true
content:
mediaTypeDeleted:
- application/json
query:
filter:
content:
mediaTypeModified:
application/json:
schema:
required:
stringsdiff:
added:
- type
image:
examples:
deleted:
- "0"
token:
schema:
maxLength:
from: 29
to: null
responses:
added:
- default
deleted:
- "200"
modified:
"201":
content:
mediaTypeModified:
application/xml:
schema:
type:
from: string
to: object
? method: GET
path: /api/{domain}/{project}/install-command
: parameters:
deleted:
header:
- network-policies
responses:
modified:
default:
description:
from: Tufin1
to: Tufin
headers:
deleted:
- X-RateLimit-Limit
servers:
added:
- https://www.tufin.io/securecloud
security:
deleted:
- bearerAuth
servers:
deleted:
- tufin.com
tags:
deleted:
- security
- reuven
externalDocs:
deleted: true
components:
schemas:
added:
- requests
modified:
network-policies:
additionalPropertiesAllowed:
from: true
to: false
rules:
additionalPropertiesAllowed:
from: null
to: false
parameters:
deleted:
header:
- network-policies
headers:
deleted:
- new
modified:
test:
schema:
additionalPropertiesAllowed:
from: true
to: false
testc:
content:
mediaTypeModified:
application/json:
schema:
type:
from: object
to: string
requestBodies:
deleted:
- reuven
responses:
added:
- default
deleted:
- OK
securitySchemes:
deleted:
- OAuth
modified:
AccessToken:
type:
from: http
to: oauth2
scheme:
from: bearer
to: ""
OAuthFlows:
added: true
diff.Get(&diff.Config{}, spec1, spec2)
See full example: main.go
-
Output Formats
- The default output format, YAML, provides a full view of all diff details.
Note that no output in YAML format signifies that the diff is empty, or, in other words, there are no changes. - Other formats: text, markdown and HTML, are designed to be more user-friendly by providing only the most important parts of the diff, in a simplified format.
If you wish to include additional details in non-YAML formats, please open an issue.
- The default output format, YAML, provides a full view of all diff details.
-
Paths vs. Endpoints
OpenAPI Specification has a hierarchial model of Paths and Operations (HTTP methods).
oasdiff respects this heirarchy and displays a hierarchial diff with path changes: added, deleted and modified, and within the latter, "modified" section, another set of operation changes: added, deleted and modified. For example:paths: deleted: - /register - /subscribe modified: /api/{domain}/{project}/badges/security-score: operations: modified: GET:
oasdiff also outputs an alternate simplified diff per "endpoint" which is a combination of Path + Operation, for example:
endpoints: deleted: - method: POST path: /subscribe - method: POST path: /register modified: ? method: GET path: /api/{domain}/{project}/badges/security-score : tags: deleted: - security
-
oasdiff expects OpenAPI References to be resolved.
References are normally resolved automatically when you load the spec. In other cases you can resolve refs using this function. -
Use configuration to exclude certain types of changes:
- Examples
- Descriptions
- Extensions are excluded by default
- Patch support: currently supports Descriptions and a few fields in Schema
- OpenAPI 3.1 support: see Tufin#52
This project relies on the excellent implementation of OpenAPI 3.0 for Go: kin-openapi