如何使用swagger在路径中定义可选参数

时间:2016-01-26 10:01:45

标签: web-services rest swagger

我的REST Web服务中有一个使用GET方法的函数,它有两个可选参数。

我尝试在Swagger中定义它,但在我将required设置为false后,我遇到了错误,不是有效的参数定义

我发现如果我将required值设置为true,错误就会消失。以下是我的Swagger代码示例。

...
paths:
  '/get/{param1}/{param2}':
    get:
      ...
      parameters:
      - name: param1
        in: path
        description: 'description regarding param1'
        required: false
        type: string
      - name: param2
        in: path
        description: 'description regarding param2'
        required: false
        type: string

我没有使用正文中的参数或查询中的参数来体验这一点。我认为这个问题只与路径中的参数有关。我也无法在swagger规范文件中找到任何解决方案。

有没有其他方法可以在Swagger中定义可选参数,或者我的代码中是否有任何错误?

任何帮助都将不胜感激。

5 个答案:

答案 0 :(得分:37)

鉴于必须根据 OpenAPI / Swagger 规范要求路径参数,您可以考虑使用以下路径添加2个单独的端点:

    提供param2时
  • /get/{param1}/{param2}
  • /get/{param1}/ 未提供param2时

答案 1 :(得分:23)

它可能会爆炸,因为你不能有一个基本的uri参数可选,只有查询字符串值(如果是url)。

例如:

  • GET / products / {id} / pricing?foo = bar
  • **如果foo是可选的,那么你的IN参数需要是"查询"不是"路径"
  • **如果{id}是可选的,那么就出错了。 {id}不可选,因为它包含在基础uri中。

这应该有效:

{
"in":"query",
"required":false
}

这不应该起作用

{
"in":"path",
"required":false
}

更改你的" in"财产是"查询"而不是"路径"它应该工作。

答案 2 :(得分:4)

您的YAML失败,因为正如规范中所述:

  

确定此参数是否必需。如果参数在“path”中,则此属性是必需的,其值必须为true。

来源:http://swagger.io/specification/#parameterObject(查看固定字段表)

答案 3 :(得分:2)

很遗憾,但事实上,在2020年和3. *规范中仍没有官方支持可选参数: https://github.com/OAI/OpenAPI-Specification/issues/93

您只能应用其他答案中提到的一些解决方法(为每个参数集描述几个端点;将您的API转换为使用查询参数而不是路径参数)。

我个人决定只保留所有内容,只需添加一个参数import 'package:flutter/material.dart'; import 'package:flutter_dialogflow/dialogflow_v2.dart'; class HomePageDialogflow extends StatefulWidget { HomePageDialogflow({Key key, this.title}) : super(key: key); final String title; @override _HomePageDialogflow createState() => new _HomePageDialogflow(); } class _HomePageDialogflow extends State<HomePageDialogflow> { final List<ChatMessage> _messages = <ChatMessage>[]; final TextEditingController _textController = new TextEditingController(); Widget _buildTextComposer() { return new IconTheme( data: new IconThemeData(color: Theme.of(context).accentColor), child: new Container( margin: const EdgeInsets.symmetric(horizontal: 8.0), child: new Row( children: <Widget>[ new Flexible( child: new TextField( controller: _textController, onSubmitted: _handleSubmitted, decoration: new InputDecoration.collapsed(hintText: "Send a message"), ), ), new Container( margin: new EdgeInsets.symmetric(horizontal: 4.0), child: new IconButton( icon: new Icon(Icons.send), onPressed: () => _handleSubmitted(_textController.text)), ), ], ), ), ); } void Response(query) async { _textController.clear(); AuthGoogle authGoogle = await AuthGoogle(fileJson: "assets/comply-267617-22528f20809f.json") .build(); Dialogflow dialogflow = Dialogflow(authGoogle: authGoogle, language: Language.english); AIResponse response = await dialogflow.detectIntent(query); ChatMessage message = new ChatMessage( text: response.getMessage() ?? new CardDialogflow(response.getListMessage()[0]).title, name: "Bot", type: false, ); setState(() { _messages.insert(0, message); }); } void _handleSubmitted(String text) { _textController.clear(); ChatMessage message = new ChatMessage( text: text, name: "Promise", type: true, ); setState(() { _messages.insert(0, message); }); Response(text); } @override Widget build(BuildContext context) { return new Scaffold( appBar: new AppBar( leading: new IconButton( icon: new Icon(Icons.arrow_back), onPressed: (){Navigator.pop(context);}), centerTitle: true, title: new Text("COMPLYNION"), ), body: new Column(children: <Widget>[ new Flexible( child: new ListView.builder( padding: new EdgeInsets.all(8.0), reverse: true, itemBuilder: (_, int index) => _messages[index], itemCount: _messages.length, )), new Divider(height: 1.0), new Container( decoration: new BoxDecoration(color: Theme.of(context).cardColor), child: _buildTextComposer(), ), ]), ); } } class ChatMessage extends StatelessWidget { ChatMessage({this.text, this.name, this.type}); final String text; final String name; final bool type; List<Widget> otherMessage(context) { return <Widget>[ new Container( margin: const EdgeInsets.only(right: 16.0), child: new CircleAvatar(child: new Text('B')), ), new Expanded( child: new Column( crossAxisAlignment: CrossAxisAlignment.start, children: <Widget>[ new Text(this.name, style: new TextStyle(fontWeight: FontWeight.bold)), new Container( margin: const EdgeInsets.only(top: 5.0), child: new Text(text), ), ], ), ), ]; } List<Widget> myMessage(context) { return <Widget>[ new Expanded( child: new Column( crossAxisAlignment: CrossAxisAlignment.end, children: <Widget>[ new Text(this.name, style: Theme.of(context).textTheme.subhead), new Container( margin: const EdgeInsets.only(top: 5.0), child: new Text(text), ), ], ), ), new Container( margin: const EdgeInsets.only(left: 16.0), child: new CircleAvatar( child: new Text( this.name[0], style: new TextStyle(fontWeight: FontWeight.bold), )), ), ]; } @override Widget build(BuildContext context) { return new Container( margin: const EdgeInsets.symmetric(vertical: 10.0), child: new Row( crossAxisAlignment: CrossAxisAlignment.start, children: this.type ? myMessage(context) : otherMessage(context), ), ); } } ,其中应明确说明“此参数是可选的!”。对于阅读API的每个人都应该足够清楚。

答案 4 :(得分:0)

尝试为同一API添加2个端点。喜欢

/get/{param1}/{param2}/get/{param1}/{param2}/{param3}