swagger-api/swagger-codegen

[Swift3] Request body cannot be an array, only a dictionary

Open

#5,480 opened on 2017年4月25日

GitHub で見る
 (5 comments) (0 reactions) (0 assignees)HTML (12,701 stars) (5,474 forks)batch import
Client: SwiftIssue: Bughelp wanted

説明

Description

The request body cannot be an array of dictionaries, or in fact an array of any object, it can only be a dictionary (which can be a dictionary containing other dictionaries as values). The issue comes from the Alamofire implementation that the request body is converted from the query parameters and the query parameters have to be a dictionary and cannot be an array.

Swagger-codegen version

2.2.2

Swagger declaration file content or url
/path/{to}/file:
    post:
      tags:
        - tag1
      operationId: something
      summary: summary
      description: 
        description
      parameters:
        - $ref: '#/parameters/param1'
        - $ref: '#/parameters/param2'
        - $ref: '#/parameters/param3'
        - name: postBody
          description: data to be posted in the body
          in: body
          required: true
          schema:
            type: array
            items:
              $ref: '#/definitions/Item1'
      responses:
        '201':
          description: Created
          schema:
            $ref: '#/definitions/Reply'

        '400':
          description: Bad request
          schema:
            $ref: '#/definitions/_Messages'
        default:
          description: Unexpected error
          schema:
            $ref: '#/definitions/_Messages'
      security:
        - basicAuth: []
Command line used for generation

swagger-codegen generate -i /path/spec.yaml -l swift3

Steps to reproduce

Generate a Swift3 client side code from a swagger spec that contains type: array in its schema for an object that is in:body.

Related issues

https://github.com/swagger-api/swagger-codegen/issues/2483 https://github.com/swagger-api/swagger-codegen/pull/4490

Suggest a Fix

The Swift file API.swift generated by swagger-codegen has the following method:

open class RequestBuilder<T> {
    var credential: URLCredential?
    var headers: [String:String]
    let parameters: [String:Any]?
    let isBody: Bool
    let method: String
    let URLString: String
    
    /// Optional block to obtain a reference to the request's progress instance when available.
    public var onProgressReady: ((Progress) -> ())?

    required public init(method: String, URLString: String, parameters: [String:Any]?, isBody: Bool, headers: [String:String] = [:]) {
        self.method = method
        self.URLString = URLString
        self.parameters = parameters
        self.isBody = isBody
        self.headers = headers
        
        addHeaders(SwaggerClientAPI.customHeaders)
    }
    
    open func addHeaders(_ aHeaders:[String:String]) {
        for (header, value) in aHeaders {
            headers[header] = value
        }
    }
    
    open func execute(_ completion: @escaping (_ response: Response<T>?, _ error: Error?) -> Void) { }

    public func addHeader(name: String, value: String) -> Self {
        if !value.isEmpty {
            headers[name] = value
        }
        return self
    }
    
    open func addCredential() -> Self {
        self.credential = SwaggerClientAPI.credential
        return self
    }
}

The problem comes from the fact that there is no body input parameter for the initialiser, only the isBody Bool, which makes it impossible to have a query parameter and a request body of different types. This is an issue, since quite a few APIs expect an array of values as the body of the request, which is not possible with the current implementation.

コントリビューターガイド

[Swift3] Request body cannot be an array, only a dictionary · swagger-api/swagger-codegen#5480 | Good First Issue