To satisfy both ease and accuracy, Request
has 2 kind of parameters properties, convenience property and actual properties. If you implement convenience parameters only, actual parameters are computed by default implementation of Request
.
Most documentations of web APIs express parameters in dictionary-like notation:
Name | Type | Description |
---|---|---|
q |
string |
The search keywords, as well as any qualifiers. |
sort |
string |
The sort field. One of stars , forks , or updated . Default: results are sorted by best match. |
order |
string |
The sort order if sort parameter is provided. One of asc or desc . Default: desc |
Request
has a property var parameter: Any?
to express parameters in this kind of notation. That is the convenience parameters.
struct SomeRequest: Request {
...
var parameters: Any? {
return [
"q": "Swift",
"sort": "stars",
"order": "desc",
]
}
}
Request
provides default implementation of parameters
nil
.
public extension Request {
public var parameters: Any? {
return nil
}
}
Actually, we have to translate dictionary-like notation in API docs into HTTP/HTTPS request. There are 2 places to express parameters, URL query and body. Request
has interface to express them, var queryParameters: [String: Any]?
and var bodyParameters: BodyParameters?
. Those are the actual parameters.
If you implement convenience parameters only, the actual parameters are computed from the convenience parameters depending on HTTP method. Here is the default implementation of actual parameters:
public extension Request {
public var queryParameters: [String: Any]? {
guard let parameters = parameters as? [String: Any], method.prefersQueryParameters else {
return nil
}
return parameters
}
public var bodyParameters: BodyParameters? {
guard let parameters = parameters, !method.prefersQueryParameters else {
return nil
}
return JSONBodyParameters(JSONObject: parameters)
}
}
If you implement actual parameters for the HTTP method, the convenience parameters will be ignored.
There are several MIME types to express parameters such as application/json
, application/x-www-form-urlencoded
and multipart/form-data; boundary=foobarbaz
. Because parameters types to express these MIME types are different, type of bodyParameters
is a protocol BodyParameters
.
BodyParameters
defines 2 components, contentType
and buildEntity()
. You can create custom body parameters type that conforms to BodyParameters
.
public enum RequestBodyEntity {
case data(Data)
case inputStream(InputStream)
}
public protocol BodyParameters {
var contentType: String { get }
func buildEntity() throws -> RequestBodyEntity
}
APIKit provides 3 body parameters type listed below:
Name | Parameters Type |
---|---|
JSONBodyParameters |
Any |
FormURLEncodedBodyParameters |
[String: Any] |
MultipartFormDataBodyParameters |
[MultipartFormDataBodyParameters.Part] |