[MIS-E001] - Delete an endpoint

Rationale

A Swagger service should be only serve endpoints defined via Swagger specs. Once an endpoint is removed from the Swagger specs this implies that the endpoint is not served anymore and any call to it will fail (as there is no implementation for it; HTTP/400, HTTP/404 or HTTP/500 could be expected in this case).

Mitigation

There are no general approaches to make this change without risks. The main recommendations are: ensure that the endpoint is marked as deprecated and notify all the clients about the endpoint removal timeline ensure that the endpoint is not called anymore.

Note: this is not always possible, think about the case of public APIs used by mobile devices. In such case validate with the clients product owners that is possible to returns errors.

PS: be aware that the fact that an endpoint is not called anymore does not implies that it won’t be called in the future (maybe the obsolete client is just not used at the moment)

Example

Old Swagger Specs

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
swagger: '2.0'
info:
  title: Minimal Case of MIS-E001 Rule
  version: '1.0'
paths:
  /endpoint:
    get:
      responses:
        default:
          description: ''
    post:
      responses:
        default:
          description: ''

New Swagger Specs

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
swagger: '2.0'
info:
  title: Minimal Case of MIS-E001 Rule
  version: '1.0'
paths:
  /endpoint:
    get:
      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
# -*- 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 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'))),
)

print('Calling the post endpoint with the old client: Succeeded')
old_client.endpoint.post_endpoint()
print('Calling the post endpoint with the new client: Failed')
try:
    new_client.endpoint.post_endpoint()
    raise RuntimeError('An error was expected')
except AttributeError:
    pass

NOTE: The code is taking advantage of bravado