git.iko.soy/typeable/compaREST
on master help sign in
330 lines 10.0 kB history raw
1# compaREST
3[![Hackage](https://img.shields.io/hackage/v/compaREST.svg?logo=haskell)](https://hackage.haskell.org/package/compaREST)
4[![MIT license](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE)
6Compatibility checker for OpenAPI
8## Using compaREST in Github Actions
10Add the following step to your Github Actions workflow:
12```yaml
13- uses: typeable/comparest
14 if: ${{ github.event_name == 'pull_request' }}
15 with:
16 old: old-openapi.yaml
17 new: new-openapi.yaml
18```
20The `new` and `old` values should be paths to your OpenAPI specifications you want to compare.
22You will get something like this in your pull requests:
24![](docs/img/github-action-report.png)
26For more detail please see our [integration guide](docs/Integration_guide.md).
28## An example
30### Your situation
32You are developing a very important server with a REST API. You have clients who use your API that you do not control. Say, you are also developing a mobile app that uses your API and you can't force someone to update to the latest version. (Or you prefer not to for UX reasons.)
34You have recently released version 1.0 and things are going great: user are downloading your app, servers are processing requests.
36You describe your API in a file `api-1.0.0.yaml`:
38```yaml
39openapi: "3.0.0"
40info:
41 version: 1.0.0
42 title: Swagger Petstore
43 license:
44 name: MIT
45servers:
46 - url: https://example.com
47paths:
48 /pets:
49 get:
50 parameters:
51 - name: limit
52 in: query
53 required: false
54 schema:
55 type: integer
56 maximum: 20
57 responses:
58 "200":
59 description: ""
60 headers:
61 x-next:
62 schema:
63 type: string
64 content:
65 application/json:
66 schema:
67 $ref: "#/components/schemas/Pets"
68 post:
69 requestBody:
70 content:
71 application/json:
72 schema:
73 $ref: "#/components/schemas/Pet"
74 responses:
75 "201":
76 description: ""
77components:
78 schemas:
79 Pet:
80 type: object
81 required:
82 - id
83 - name
84 properties:
85 id:
86 type: integer
87 name:
88 type: string
89 minLength: 3
90 maxLength: 10
91 Pets:
92 type: array
93 items:
94 $ref: "#/components/schemas/Pet"
95```
97### Evolving your product
99Enthused over your initial success you hurry to release a new and improved version of your API and mobile app.
101After a round of very intense programming you take a look at your new `api-1.1.0.yaml`:
103```yaml
104openapi: "3.0.0"
105info:
106 version: 1.1.0
107 title: Swagger Petstore
108 license:
109 name: MIT
110servers:
111 - url: https://example.com
112paths:
113 /pets:
114 get:
115 parameters:
116 - name: limit
117 in: query
118 required: false
119 schema:
120 type: integer
121 maximum: 30
122 responses:
123 "200":
124 description: ""
125 headers:
126 x-next:
127 schema:
128 type: string
129 content:
130 application/json:
131 schema:
132 $ref: "#/components/schemas/Pets"
133 post:
134 requestBody:
135 content:
136 application/json:
137 schema:
138 $ref: "#/components/schemas/Pet"
139 responses:
140 "201":
141 description: ""
142components:
143 schemas:
144 Pet:
145 type: object
146 required:
147 - id
148 - name
149 properties:
150 id:
151 type: integer
152 name:
153 type: string
154 minLength: 1
155 maxLength: 15
156 weight:
157 type: integer
158 Pets:
159 type: array
160 items:
161 $ref: "#/components/schemas/Pet"
162```
164Looking at the very large and complex API description, you grow more and more concerned that your old mobile app might stop working when you update the server. But the spec is too large and too complex to reasonably assess this manually.
166### Assessing compatibility automatically
168Luckily, you have access to compaREST which can programmatically analyze your APIs and determine what, if anything, breaks compatibility and what doesn't.
170You can call it, passing the API your client will be aware of, and the API your server will serve like so:
172```bash
173docker run --rm -v $(pwd):/data:rw typeable/comparest --client /data/api-1.0.0.yaml --server /data/api-1.1.0.yaml --output /data/report.md
174```
176Running this command will output a file `report.md`, containing the compatibility report between the two APIs:
178> # Summary
180> | [❌ Breaking changes](#breaking-changes) | [⚠️ Non-breaking changes](#non-breaking-changes) |
181> |------------------------------------------|--------------------------------------------------|
182> | 5 | 6 |
184> # <span id="breaking-changes"></span>❌ Breaking changes
186> ## **GET** /pets
188> ### ⬅️☁️ JSON Response – 200
190> #### `$[*].name(String)`
192> 1. Maximum length of the string changed from 10 to 15.
194> 2. Minimum length of the string changed from 3 to 1.
196> ## **POST** /pets
198> ### ➡️☁️ JSON Request
200> #### `$.weight`
202> 1. Values are now limited to the following types:
204> - Number
206> 2. The property was previously implicitly described by the catch-all
207> "additional properties" case. It is now explicitly defined.
209> #### `$.weight(Number)`
211> Value is now a multiple of 1.0.
213> # <span id="non-breaking-changes"></span>⚠️ Non-breaking changes
215> ## **GET** /pets
217> ### Parameter limit
219> #### JSON Schema
221> ##### `$(Number)`
223> Upper bound changed from 20.0 inclusive to 30.0 inclusive.
225> ### ⬅️☁️ JSON Response – 200
227> #### `$[*].weight`
229> 1. Values are now limited to the following types:
231> - Number
233> 2. The property was previously implicitly described by the catch-all
234> "additional properties" case. It is now explicitly defined.
236> #### `$[*].weight(Number)`
238> Value is now a multiple of 1.0.
240> ## **POST** /pets
242> ### ➡️☁️ JSON Request
244> #### `$.name(String)`
246> 1. Maximum length of the string changed from 10 to 15.
248> 2. Minimum length of the string changed from 3 to 1.
250You now know exactly in what situations and in what way your 1.0 version of the app will break if you deploy your 1.1 version of the server.
252### Additional formats
254You can also produce a self-contained HTML report that you can open in your browser by simply omitting the file extension of the output file:
256```bash
257docker run --rm -v $(pwd):/data:rw typeable/comparest --client /data/api-1.0.0.yaml --server /data/api-1.1.0.yaml --output /data/report
258```
260## CLI docs
262For more detail please see our [user guide](docs/User_guide.md).
264```
265Usage: comparest (-c|--client ARG) (-s|--server ARG)
266 [--silent | --only-breaking | --all] [-o|--output ARG]
267 [--folding-block-quotes-style | --header-style]
268 [--signal-exit-code]
269 A tool to check compatibility between two OpenAPI specifications.
271 Usage examples
273 Compare files old.yaml with new.yaml and output the resulting report to
274 stdout:
276 comparest -c old.yaml -s new.yaml
278 Only output breaking changes and write a styled HTML report to file
279 report.html:
281 comparest -c old.yaml -s new.yaml --only-breaking -o report
283 Don't output anything, only fail if there are breaking changes:
285 comparest -c old.json -s new.json --silent
287 Write full report suitable for embedding into a GitHub comment to
288 report.html:
290 comparest -c old.json -s new.json --folding-block-quotes-style -o report.html
292Available options:
293 -h,--help Show this help text
294 -c,--client ARG A path to the file containing the specification that
295 will be used for the client of the API. Can be either
296 a YAML or JSON file.
297 -s,--server ARG A path to the file containing the specification that
298 will be used for the server of the API. Can be either
299 a YAML or JSON file.
300 --silent Silence all output. Only makes sense in combination
301 with --signal-exit-code.
302 --only-breaking Only report breaking changes in the output.
303 --all Report both incompatible and compatible changes.
304 Compatible changes will not trigger a failure exit
305 code.
306 -o,--output ARG The file path where the output should be written. If
307 the option is omitted the result will be written to
308 stdout.
310 The file extension is used to determine the type of
311 the output file.
313 Supports many formats such as markdown, html, rtf,
314 doc, txt, rst, and many more.
316 Leave out the extension to produce a self-contained
317 HTML report with styling.
318 --folding-block-quotes-style
319 The report tree is structured using summary/detail
320 HTML elements and indented using block quotes. This
321 style renders well on GitHub.Intended for HTML output
322 format. Markdown has rendering bugs on GitHub.
323 --header-style The report tree is structured using increasing levels
324 of headers.
325 --signal-exit-code Signal API compatibility with the exit code.
327 Exit with 0 if there are no breaking changes.
328 Exit with 1 if there are breaking changes.
329 Exit with 2 if could not determine compatibility.
330```