[REQ-E001] - Added Required Property in Request contract¶
Rationale¶
Adding a required property to an object used in requests leads client request to fail if the property is not present.
Mitigation¶
A possible mitigation consists of adding the property as optional with an associated default value. In this case, the client requests don’t fail to validate and the service can assume that the property is always set.
Example¶
Old Swagger Specs¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | swagger: '2.0'
info:
title: Minimal Case of REQ-E001 Rule
version: '1.0'
paths:
/endpoint:
post:
parameters:
- in: body
name: body
required: true
schema:
properties:
property:
type: string
type: object
responses:
default:
description: ''
|
New Swagger Specs¶
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | swagger: '2.0'
info:
title: Minimal Case of REQ-E001 Rule
version: '1.0'
paths:
/endpoint:
post:
parameters:
- in: body
name: body
required: true
schema:
properties:
property:
type: string
required:
- property
type: object
responses:
default:
description: ''
|
Backward Incompatibility¶
The following snippet triggers the incompatibility error.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | # -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import print_function
from __future__ import unicode_literals
from os.path import abspath
from bravado.client import SwaggerClient
from jsonschema import ValidationError
from six.moves.urllib.parse import urljoin
from six.moves.urllib.request import pathname2url
old_client = SwaggerClient.from_url(
spec_url=urljoin('file:', pathname2url(abspath('old.yaml'))),
)
new_client = SwaggerClient.from_url(
spec_url=urljoin('file:', pathname2url(abspath('new.yaml'))),
)
object_to_send = {}
print('Calling the post endpoint with the old client: Succeeded')
old_client.endpoint.post_endpoint(body=object_to_send)
print('Calling the post endpoint with the new client: Failed')
try:
new_client.endpoint.post_endpoint(body=object_to_send)
raise RuntimeError('An error was expected')
except ValidationError:
pass
|
NOTE: The code is taking advantage of bravado