Skip to content

Commit 2756ad3

Browse files
villain-bramosbugs
andauthored
Fix query param array with reference (#1)
This commit fixes an error in the codegen for API request param defined as array which reference another schema object. The generated code to parse an individual array item used the argument type (`Vec<TheType>`) so the generated code didn't compile (trying to `p.parse::<Vec<TheType>>()` instead of `p.parse::<TheType>()`). --------- Co-authored-by: David A. Ramos <ramos@cs.stanford.edu>
1 parent 484f410 commit 2756ad3

File tree

5 files changed

+107
-1
lines changed

5 files changed

+107
-1
lines changed

openapi-lambda-codegen/src/api/operation/parameter.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,15 @@ impl CodeGenerator {
6767
})),
6868
..
6969
}) => match item_ref_or_schema {
70-
ReferenceOr::Reference { .. } => Some(required_type.clone()),
70+
ReferenceOr::Reference { .. } => Some(
71+
self
72+
.inline_ref_or_schema(
73+
item_ref_or_schema,
74+
components_schemas,
75+
GeneratedModels::Done(generated_models),
76+
)
77+
.0,
78+
),
7179
ReferenceOr::Item(item_schema) if !is_plain_string_schema(item_schema) => Some(
7280
self
7381
.inline_ref_or_schema(

openapi-lambda-test/spec/bar.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,19 @@ path:
2222
- B
2323
- "1"
2424
- ""
25+
- name: type-array
26+
in: query
27+
description: Bar array type
28+
schema:
29+
type: array
30+
items:
31+
type: string
32+
# Inline enum should generate a new model.
33+
enum:
34+
- a
35+
- B
36+
- "1"
37+
- ""
2538
- name: x-bar
2639
in: header
2740
schema:

openapi-lambda-test/src/snapshots/openapi_lambda_test__tests__bar_handler.rs.snap

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ impl Api for BarApiHandler {
4444
bar_id: crate::types::BarId,
4545
sort_by: Option<crate::models::SortBy>,
4646
r#type: Option<crate::models::CreateBarTypeParam>,
47+
type_array: Option<Vec<crate::models::CreateBarTypeArrayParamItem>>,
4748
x_bar: Option<String>,
4849
request_body: Vec<u8>,
4950
headers: HeaderMap,

openapi-lambda-test/src/snapshots/openapi_lambda_test__tests__openapi-apigw.yaml.snap

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,14 @@ paths:
6868
schema:
6969
$ref: "#/components/schemas/CreateBarTypeParam"
7070
style: form
71+
- in: query
72+
name: type-array
73+
description: Bar array type
74+
schema:
75+
type: array
76+
items:
77+
$ref: "#/components/schemas/CreateBarTypeArrayParamItem"
78+
style: form
7179
- in: header
7280
name: x-bar
7381
schema:
@@ -134,6 +142,13 @@ components:
134142
- B
135143
- "1"
136144
- ""
145+
CreateBarTypeArrayParamItem:
146+
type: string
147+
enum:
148+
- a
149+
- B
150+
- "1"
151+
- ""
137152
responses:
138153
FooOk:
139154
description: Successful operation

openapi-lambda-test/src/snapshots/openapi_lambda_test__tests__out.rs.snap

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,44 @@ pub mod models {
1010
use openapi_lambda::models::chrono;
1111
#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, Hash)]
1212
#[serde(crate = "openapi_lambda::__private::serde")]
13+
pub enum CreateBarTypeArrayParamItem {
14+
#[serde(rename = "a")]
15+
A,
16+
B,
17+
#[serde(rename = "1")]
18+
__1,
19+
#[serde(rename = "")]
20+
EmptyString,
21+
}
22+
impl CreateBarTypeArrayParamItem {
23+
fn as_str(&self) -> &'static str {
24+
match self {
25+
Self::A => "a",
26+
Self::B => "B",
27+
Self::__1 => "1",
28+
Self::EmptyString => "",
29+
}
30+
}
31+
}
32+
impl std::fmt::Display for CreateBarTypeArrayParamItem {
33+
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
34+
write!(f, "{}", self.as_str())
35+
}
36+
}
37+
impl std::str::FromStr for CreateBarTypeArrayParamItem {
38+
type Err = anyhow::Error;
39+
fn from_str(s: &str) -> Result<Self, Self::Err> {
40+
match s {
41+
"a" => Ok(Self::A),
42+
"B" => Ok(Self::B),
43+
"1" => Ok(Self::__1),
44+
"" => Ok(Self::EmptyString),
45+
_ => Err(anyhow!("invalid enum variant `{}`", s)),
46+
}
47+
}
48+
}
49+
#[derive(Clone, Copy, Debug, Deserialize, Serialize, PartialEq, Eq, Hash)]
50+
#[serde(crate = "openapi_lambda::__private::serde")]
1351
pub enum CreateBarTypeParam {
1452
#[serde(rename = "a")]
1553
A,
@@ -230,6 +268,7 @@ pub mod bar {
230268
#[doc = concat!("* `", stringify!(bar_id), "` - ", "")]
231269
#[doc = concat!("* `", stringify!(sort_by), "` - ", "")]
232270
#[doc = concat!("* `", stringify!(r#type), "` - ", "Bar type")]
271+
#[doc = concat!("* `", stringify!(type_array), "` - ", "Bar array type")]
233272
#[doc = concat!("* `", stringify!(x_bar), "` - ", "")]
234273
#[doc = concat!("* `request_body` - ", "Request body")]
235274
/// * `headers` - HTTP request headers
@@ -244,6 +283,7 @@ pub mod bar {
244283
bar_id: crate::types::BarId,
245284
sort_by: Option<crate::models::SortBy>,
246285
r#type: Option<crate::models::CreateBarTypeParam>,
286+
type_array: Option<Vec<crate::models::CreateBarTypeArrayParamItem>>,
247287
x_bar: Option<String>,
248288
request_body: Vec<u8>,
249289
headers: HeaderMap,
@@ -360,6 +400,31 @@ pub mod bar {
360400
Err(err) => return api.respond_to_event_error(err).await,
361401
};
362402
#[allow(clippy::bind_instead_of_map)]
403+
let type_array = match request
404+
.multi_value_query_string_parameters
405+
.all("type-array")
406+
.map(|param_values| {
407+
param_values
408+
.iter()
409+
.copied()
410+
.map(|p| {
411+
p.parse::<crate::models::CreateBarTypeArrayParamItem>()
412+
.map_err(|err| {
413+
EventError::InvalidRequestQueryParam {
414+
param_name: std::borrow::Cow::Borrowed("type-array"),
415+
source: Some(err.into()),
416+
backtrace: Backtrace::new(),
417+
}
418+
})
419+
})
420+
.collect::<Result<Vec<_>, _>>()
421+
})
422+
.transpose()
423+
{
424+
Ok(param_value) => param_value,
425+
Err(err) => return api.respond_to_event_error(err).await,
426+
};
427+
#[allow(clippy::bind_instead_of_map)]
363428
let x_bar = match request
364429
.headers
365430
.get("x-bar")
@@ -447,6 +512,9 @@ pub mod bar {
447512
log::trace!(concat!("Request parameter `", "barId", "`: {:#?}"), bar_id);
448513
log::trace!(concat!("Request parameter `", "sortBy", "`: {:#?}"), sort_by);
449514
log::trace!(concat!("Request parameter `", "type", "`: {:#?}"), r#type);
515+
log::trace!(
516+
concat!("Request parameter `", "type-array", "`: {:#?}"), type_array
517+
);
450518
log::trace!(concat!("Request parameter `", "x-bar", "`: {:#?}"), x_bar);
451519
log::trace!("Request body: {request_body:#?}");
452520
log::trace!("Authenticating request");
@@ -470,6 +538,7 @@ pub mod bar {
470538
bar_id,
471539
sort_by,
472540
r#type,
541+
type_array,
473542
x_bar,
474543
request_body,
475544
headers,

0 commit comments

Comments
 (0)