Problem
Currently, pacto diff only supports OpenAPI specs for deep interface contract diffing. When an interface references a contract file, it is always parsed as OpenAPI regardless of the interface type. Services using other API paradigms (gRPC/protobuf, async messaging via AsyncAPI, or GraphQL) have no contract-level diffing — only the contract file path change is detected, not the actual API changes within.
Proposed Solution
Add deep diff support for additional interface contract formats:
- gRPC (Protocol Buffers): Diff
.proto files — detect added/removed services, methods, message fields, and field number changes. Field removals and number changes should be classified as BREAKING.
- AsyncAPI: Diff AsyncAPI specs — detect channel, message, and schema changes. Similar hierarchical approach to the current OpenAPI diffing.
- GraphQL: Diff GraphQL schemas — detect type, field, query, mutation, and subscription changes. Removing fields/types should be
BREAKING.
Each format should follow the same pattern established by the OpenAPI differ:
- A
diff<Format> function called from interfaces.go based on interface type or file extension
- A hierarchical traversal producing
Change entries with appropriate paths
- Classification rules added to the lookup table in
classification.go
Alternatives Considered
- Relying on external tools (e.g.,
buf breaking for protobuf, graphql-inspector for GraphQL) and integrating their output. This would add external dependencies and inconsistent output formats.
- Treating all non-OpenAPI contracts as opaque files (only detecting file-level changes). This is the current behavior and loses valuable change detail.
Area
Contract specification
Additional Context
The branching point in the code is internal/diff/interfaces.go:41-45, where diffOpenAPI is called unconditionally for any interface with a contract file. This would need to dispatch to the appropriate differ based on interface type or contract file extension.
Problem
Currently,
pacto diffonly supports OpenAPI specs for deep interface contract diffing. When an interface references a contract file, it is always parsed as OpenAPI regardless of the interfacetype. Services using other API paradigms (gRPC/protobuf, async messaging via AsyncAPI, or GraphQL) have no contract-level diffing — only the contract file path change is detected, not the actual API changes within.Proposed Solution
Add deep diff support for additional interface contract formats:
.protofiles — detect added/removed services, methods, message fields, and field number changes. Field removals and number changes should be classified asBREAKING.BREAKING.Each format should follow the same pattern established by the OpenAPI differ:
diff<Format>function called frominterfaces.gobased on interface type or file extensionChangeentries with appropriate pathsclassification.goAlternatives Considered
buf breakingfor protobuf,graphql-inspectorfor GraphQL) and integrating their output. This would add external dependencies and inconsistent output formats.Area
Contract specification
Additional Context
The branching point in the code is
internal/diff/interfaces.go:41-45, wherediffOpenAPIis called unconditionally for any interface with a contract file. This would need to dispatch to the appropriate differ based on interface type or contract file extension.