The documentation says that strict_validation should return a 400, however it appears to be returning a 404 instead
Per the documentation at https://connexion.readthedocs.io/en/latest/request.html#parameter-validation
Connexion can apply strict parameter validation for query and form data parameters. When this is enabled, requests that include parameters not defined in the swagger spec return a 400 error.
Connexion returns a 400 Bad Request when a parameter does not match the schema
Connexion returns a 404 Not Found when a parameter does not match the schema
connexion issue> curl -i localhost:5000/has-param/1
HTTP/1.0 200 OK
Content-Type: application/json
Content-Length: 2
Server: Werkzeug/0.14.1 Python/3.6.4
Date: Fri, 09 Nov 2018 19:31:03 GMT
1
connexion issue> curl -i localhost:5000/has-param/a
HTTP/1.0 404 NOT FOUND
Content-Type: application/problem+json
Content-Length: 206
Server: Werkzeug/0.14.1 Python/3.6.4
Date: Fri, 09 Nov 2018 19:30:55 GMT
{
"detail": "The requested URL was not found on the server. If you entered the URL manually please check your spelling and try again.",
"status": 404,
"title": "Not Found",
"type": "about:blank"
}
```main.py
import connexion
from connexion.resolver import RestyResolver
def get_has_param(demoId):
return demoId
if __name__ == '__main__':
app = connexion.FlaskApp(__name__)
app.add_api(
'request-validation-demo.yaml',
validate_responses=True,
strict_validation=True,
)
app.run()
#### Sample OpenAPI v3 Document
openapi: 3.0.0
info:
title: This should be returning a 400 on an invalid parameter
version: '0'
paths:
/has-param/{demoId}:
get:
summary: This should be returning a 400 when it gets an invalid parameter, not a 404
operationId: main.get_has_param
parameters:
- name: demoId
in: path
required: true
description: This should be a 400 when invalid
schema:
type: integer
responses:
200:
description: Demo Result
content:
application/json:
schema:
type: integer
400:
description: Demo 400
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
404:
description: Demo 404
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
components:
schemas:
Error:
required:
- code
- message
properties:
code:
type: integer
message:
type: string
### Additional info:
Output of the commands:
connexion issue> python3 --version
Python 3.6.4
connexion issue> pip3 show connexion | grep "^Version\:"
Version: 2.0.1
connexion issue>
```
I think what's happening is that the path parameters generate routes for Flask.
The route that's being generated here is something like: /has-param/<demoId:int>: and so Flask is unable to match /has-param/a to this pattern, and returns a 404.
We could drop all types from Flask routes to ensure that parameters make it through to validation - I'm not sure yet what the full implications of that would be. I'll try to play around with it today.
I just worked through an issue with similar symptoms (I'm guessing it's the same core issue, but someone with a deeper knowledge of connexion may know better).
I added a new path to an existing (and working) project, but was getting 404s in all cases while testing. I narrowed it down to this trivial reproduction case:
Openapi spec:
...
/games/{game_id}:
get:
summary: Game_GET
description: blah testing
operationId: main.foo
parameters:
- name: game_id
in: path
description: ID of the game being played
required: true
schema:
type: number
...
With the corresponding handler:
def foo(game_id):
return {'hi': game_id}, 200
All calls to .../games/<n> would return a 404. Reading this bug led me to noticed I'd inadvertently specified the parameter type as number rather than integer - when I changed it back to integer all was well.
In my case, I intended the parameter to be an int, so number in the spec was just a mistake. But since number is the way to specify a float per the openapi spec, though, I wonder how one would get connexion routing to work with a float parameter.
Most helpful comment
I think what's happening is that the path parameters generate routes for Flask.
The route that's being generated here is something like:
/has-param/<demoId:int>:and so Flask is unable to match/has-param/ato this pattern, and returns a 404.We could drop all types from Flask routes to ensure that parameters make it through to validation - I'm not sure yet what the full implications of that would be. I'll try to play around with it today.