The issue is almost new and seems to be related to the use of the new nlohmann::json API (?)
When a request has been described in YAML with a body content owning 2 fields (only one required), if the client sends the request with only one field, the pistache-server rejects and answer with a HTTP 500 - "[json.exception.out_of_range.403] key 'field2' not found"
I must add that the 'field2' was defined as a 'anyOf' string, see below.
Current master 4.0.0-SNAPSHOT
This is a regression. It has worked, at least, up to the commit 84b99fea546ec116e399625239a6991ebabd3a94
openapi: "3.0.0"
info:
version: 1.0.0
title: Check anyOf in request content
servers:
- url: '{apiRoot}/'
variables:
apiRoot:
default: https://example.com
description: Internal ref filename is check_anyOf_in_req_content.yaml
paths:
/CheckAnyOf:
post:
summary: Check AnyOf generation
operationId: list
tags:
- Check
requestBody:
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/Content"
responses:
'200':
description: Everythings gonna be alright
headers:
x-next:
description: Everythings gonna be alright
schema:
type: string
content:
application/json:
schema:
type: string
default:
description: unexpected error
content:
application/json:
schema:
type: string
components:
schemas:
PresenceState:
anyOf:
- type: string
enum:
- "IN"
- "OUT"
- "UNKNOWN"
- type: string
Content:
type: object
required:
- field1
properties:
field1:
type: string
field2:
$ref: "#/components/schemas/PresenceState"
Generate :
openapi-generator-cli.sh generate -i ./openapi.yaml -g cpp-pistache-server -c ./config.json -o .
Compile all files and link:
(cd impl && ln -s ../main-api-server.cpp ./main.cpp)
g++ -c -I./api -I./model -I./impl -Wall -g -std=c++11 -o obj/api/CheckApi.o api/CheckApi.cpp
g++ -c -I./api -I./model -I./impl -Wall -g -std=c++11 -o obj/impl/CheckApiImpl.o impl/CheckApiImpl.cpp
g++ -c -I./api -I./model -I./impl -Wall -g -std=c++11 -o obj/impl/main.o impl/main.cpp
g++ -c -I./api -I./model -I./impl -Wall -g -std=c++11 -o obj/model/Content.o model/Content.cpp
g++ -c -I./api -I./model -I./impl -Wall -g -std=c++11 -o obj/model/PresenceState.o model/PresenceState.cpp
g++ -c -I./api -I./model -I./impl -Wall -g -std=c++11 -o obj/model/Helpers.o model/Helpers.cpp
ar -rc obj/model/libmodel.a obj/model/Content.o obj/model/PresenceState.o obj/model/Helpers.o
g++ -g -o server-MsUnderTest obj/api/CheckApi.o obj/impl/CheckApiImpl.o obj/impl/main.o obj/model/libmodel.a -lpistache -lpthread
Launch the generated server listening on the TCP port 8080
Send the request with only 1 field content, with curl (for example) :
curl -X POST "http://localhost:8080/CheckAnyson" -H "Content-Type: application/json" -d "{\"field1\":\"string\"}"
The result will be :
[json.exception.out_of_range.403] key 'field2' not found
Send the request with the 2 fields :
curl -X POST "http://localhost:8080/CheckAnyOf" -H "accept: application/json" -H "Content-Type: application/json" -d "{\"field1\":\"string\",\"field2\":\"string\"}"
The result will be :
"Everythings gonna be alright"
N/A
One suggested fix in the comment below
EDIT: One patch delivered to fix the appropriated code. See below
馃憤 Thanks for opening this issue!
馃彿 I have applied any labels matching special text in your issue.
The team will review the labels and make any necessary changes.
I worked on this regression and I have identified the generated code that throw an json exception :
void from_json(const nlohmann::json& j, Content& o)
{
j.at("field1").get_to(o.m_Field1);
/*
* The call to j.at("field2") will throw a JSON exception out_of_range - 403 - key not found
* before calling the is_null() method
*/
if(!j.at("field2").is_null())
{
j.at("field2").get_to(o.m_Field2);
o.m_Field2IsSet = true;
}
}
EDIT: That's for @etherealjoy (^_^)
Fix should be this kind of generated code :
void from_json(const nlohmann::json& j, Content& o)
{
j.at("field1").get_to(o.m_Field1);
#ifdef BEFORE_FIX
if(!j.at("field2").is_null())
{
j.at("field2").get_to(o.m_Field2);
o.m_Field2IsSet = true;
}
#else
{
auto it=j.find("field2") ;
if( it != j.cend() )
{
it->get_to(o.m_Field2) ;
o.m_Field2IsSet = true;
}
}
#endif
}
Below the patch to apply to the mustache file :
cd ./modules/openapi-generator/src/main/resources/cpp-pistache-server
patch -N -t -p0 < file.patch.txt
It will generate some kind of code as described above for each required field.
I hope the next time I will be able to submit a PR ... as soon as I would have understood how to ^^
Thanks for the patch. I can help you create the PR.
Lets fix this first before we work on the other Pistache issues
Agree and the fix is better than mine :+1: