Skip to content

Commit 25bd154

Browse files
author
Timo Rohrberg
committed
Fix Issue #136 new read-only property breaks PUT
Adding a new read-only property into an API model should be considered a breaking change for PUT operations. A client not knowing of the new read-only property would get a resource from the API which includes the new read-only property and would send a full update back via PUT omitting that new property. The result is that the property would be cleared on the server side as the client did not sent the retrieved value back.
1 parent 443246f commit 25bd154

File tree

4 files changed

+176
-2
lines changed

4 files changed

+176
-2
lines changed

src/main/java/com/qdesrame/openapi/diff/model/ChangedSchema.java

+10-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.qdesrame.openapi.diff.model;
22

33
import com.qdesrame.openapi.diff.model.schema.*;
4+
import io.swagger.v3.oas.models.PathItem;
45
import io.swagger.v3.oas.models.media.Schema;
56
import java.util.LinkedHashMap;
67
import java.util.List;
@@ -76,15 +77,22 @@ public DiffResult isCoreChanged() {
7677
&& !discriminatorPropertyChanged) {
7778
return DiffResult.NO_CHANGES;
7879
}
79-
boolean compatibleForRequest = (oldSchema != null || newSchema == null);
8080
boolean compatibleForResponse =
8181
missingProperties.isEmpty() && (oldSchema == null || newSchema != null);
82-
if ((context.isRequest() && compatibleForRequest
82+
if ((context.isRequest() && compatibleForRequest()
8383
|| context.isResponse() && compatibleForResponse)
8484
&& !changedType
8585
&& !discriminatorPropertyChanged) {
8686
return DiffResult.COMPATIBLE;
8787
}
8888
return DiffResult.INCOMPATIBLE;
8989
}
90+
91+
private boolean compatibleForRequest() {
92+
if (PathItem.HttpMethod.PUT.equals(context.getMethod())) {
93+
if (increasedProperties.size() > 0) return false;
94+
}
95+
96+
return (oldSchema != null || newSchema == null);
97+
}
9098
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.qdesrame.openapi.test;
2+
3+
import static com.qdesrame.openapi.test.TestUtils.assertOpenApiAreEquals;
4+
import static com.qdesrame.openapi.test.TestUtils.assertOpenApiBackwardIncompatible;
5+
6+
import org.junit.jupiter.api.Test;
7+
8+
/** Created by trohrberg on 23/03/19. */
9+
public class AddPropPutDiffTest {
10+
private final String OPENAPI_DOC1 = "add-prop-put-1.yaml";
11+
private final String OPENAPI_DOC2 = "add-prop-put-2.yaml";
12+
13+
@Test
14+
public void testDiffSame() {
15+
assertOpenApiAreEquals(OPENAPI_DOC1, OPENAPI_DOC1);
16+
}
17+
18+
@Test
19+
public void testDiffDifferent() {
20+
assertOpenApiBackwardIncompatible(OPENAPI_DOC1, OPENAPI_DOC2);
21+
}
22+
}
+71
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
openapi: 3.0.0
2+
servers:
3+
- description: SwaggerHub API Auto Mocking
4+
url: https://virtserver.swaggerhub.com/anshul10s/pet-store/1.0.0
5+
info:
6+
description: |
7+
This is a sample Petstore server. You can find
8+
out more about Swagger at
9+
[http://swagger.io](http://swagger.io) or on
10+
[irc.freenode.net, #swagger](http://swagger.io/irc/).
11+
version: "1.0.0"
12+
title: Swagger Petstore
13+
termsOfService: 'http://swagger.io/terms/'
14+
contact:
15+
16+
license:
17+
name: Apache 2.0
18+
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
19+
tags:
20+
- name: pet
21+
description: Everything about your Pets
22+
externalDocs:
23+
description: Find out more
24+
url: 'http://swagger.io'
25+
- name: store
26+
description: Access to Petstore orders
27+
- name: user
28+
description: Operations about user
29+
externalDocs:
30+
description: Find out more about our store
31+
url: 'http://swagger.io'
32+
paths:
33+
/store/inventory/{id}:
34+
put:
35+
tags:
36+
- store
37+
summary: Updates the inventory with the given id
38+
description: Updates the inventory with the given id and returns it
39+
operationId: putInventory
40+
parameters:
41+
- name: id
42+
in: path
43+
description: Unique Id of the inventory
44+
required: true
45+
example: a-b-c-d
46+
schema:
47+
type: string
48+
requestBody:
49+
content:
50+
application/json:
51+
schema:
52+
$ref: '#/components/schemas/Inventory'
53+
responses:
54+
'200':
55+
description: successful operation
56+
content:
57+
application/json:
58+
schema:
59+
$ref: '#/components/schemas/Inventory'
60+
externalDocs:
61+
description: Find out more about Swagger
62+
url: 'http://swagger.io'
63+
components:
64+
schemas:
65+
Inventory:
66+
type: object
67+
properties:
68+
id:
69+
type: string
70+
details:
71+
type: count
+73
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
openapi: 3.0.0
2+
servers:
3+
- description: SwaggerHub API Auto Mocking
4+
url: https://virtserver.swaggerhub.com/anshul10s/pet-store/1.0.0
5+
info:
6+
description: |
7+
This is a sample Petstore server. You can find
8+
out more about Swagger at
9+
[http://swagger.io](http://swagger.io) or on
10+
[irc.freenode.net, #swagger](http://swagger.io/irc/).
11+
version: "1.0.0"
12+
title: Swagger Petstore
13+
termsOfService: 'http://swagger.io/terms/'
14+
contact:
15+
16+
license:
17+
name: Apache 2.0
18+
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
19+
tags:
20+
- name: pet
21+
description: Everything about your Pets
22+
externalDocs:
23+
description: Find out more
24+
url: 'http://swagger.io'
25+
- name: store
26+
description: Access to Petstore orders
27+
- name: user
28+
description: Operations about user
29+
externalDocs:
30+
description: Find out more about our store
31+
url: 'http://swagger.io'
32+
paths:
33+
/store/inventory/{id}:
34+
put:
35+
tags:
36+
- store
37+
summary: Updates the inventory with the given id
38+
description: Updates the inventory with the given id and returns it
39+
operationId: putInventory
40+
parameters:
41+
- name: id
42+
in: path
43+
description: Unique Id of the inventory
44+
required: true
45+
example: a-b-c-d
46+
schema:
47+
type: string
48+
requestBody:
49+
content:
50+
application/json:
51+
schema:
52+
$ref: '#/components/schemas/Inventory'
53+
responses:
54+
'200':
55+
description: successful operation
56+
content:
57+
application/json:
58+
schema:
59+
$ref: '#/components/schemas/Inventory'
60+
externalDocs:
61+
description: Find out more about Swagger
62+
url: 'http://swagger.io'
63+
components:
64+
schemas:
65+
Inventory:
66+
type: object
67+
properties:
68+
id:
69+
type: string
70+
details:
71+
type: count
72+
extra_info:
73+
type: string

0 commit comments

Comments
 (0)