Skip to content
Merged
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ import {{packageName}}.infrastructure.Serializer
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}companion object {
@JvmStatic
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val defaultBasePath: String by lazy {
System.getProperties().getProperty(ApiClient.baseUrlKey, "{{{basePath}}}")
System.getProperties().getProperty(ApiClient.BASE_URL_KEY, "{{{basePath}}}")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,22 +63,81 @@ import com.squareup.moshi.adapter

{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}open class ApiClient({{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val baseUrl: String, {{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val client: Call.Factory = defaultClient) {
{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}companion object {
protected const val ContentType: String = "Content-Type"
protected const val Accept: String = "Accept"
protected const val Authorization: String = "Authorization"
protected const val JsonMediaType: String = "application/json"
protected const val FormDataMediaType: String = "multipart/form-data"
protected const val FormUrlEncMediaType: String = "application/x-www-form-urlencoded"
protected const val XmlMediaType: String = "application/xml"
protected const val OctetMediaType: String = "application/octet-stream"
protected const val TextMediaType: String = "text/plain"
protected const val CONTENT_TYPE: String = "Content-Type"
@Deprecated(
message = "Please use the capitalized constant `CONTENT_TYPE` instead.",
replaceWith = ReplaceWith("CONTENT_TYPE")
)
protected const val ContentType: String = CONTENT_TYPE

protected const val ACCEPT: String = "Accept"
@Deprecated(
message = "Please use the capitalized constant `ACCEPT` instead.",
replaceWith = ReplaceWith("ACCEPT")
)
protected const val Accept: String = ACCEPT

protected const val AUTHORIZATION: String = "Authorization"
@Deprecated(
message = "Please use the capitalized constant `AUTHORIZATION` instead.",
replaceWith = ReplaceWith("AUTHORIZATION")
)
protected const val Authorization: String = AUTHORIZATION

protected const val JSON_MEDIA_TYPE: String = "application/json"
@Deprecated(
message = "Please use the capitalized constant `JSON_MEDIA_TYPE` instead.",
replaceWith = ReplaceWith("JSON_MEDIA_TYPE")
)
protected const val JsonMediaType: String = JSON_MEDIA_TYPE

protected const val FORM_DATA_MEDIA_TYPE: String = "multipart/form-data"
@Deprecated(
message = "Please use the capitalized constant `FORM_DATA_MEDIA_TYPE` instead.",
replaceWith = ReplaceWith("FORM_DATA_MEDIA_TYPE")
)
protected const val FormDataMediaType: String = FORM_DATA_MEDIA_TYPE

protected const val FORM_URL_ENC_MEDIA_TYPE: String = "application/x-www-form-urlencoded"
@Deprecated(
message = "Please use the capitalized constant `FORM_URL_ENC_MEDIA_TYPE` instead.",
replaceWith = ReplaceWith("FORM_URL_ENC_MEDIA_TYPE")
)
protected const val FormUrlEncMediaType: String = FORM_URL_ENC_MEDIA_TYPE

protected const val XML_MEDIA_TYPE: String = "application/xml"
@Deprecated(
message = "Please use the capitalized constant `XML_MEDIA_TYPE` instead.",
replaceWith = ReplaceWith("XML_MEDIA_TYPE")
)
protected const val XmlMediaType: String = XML_MEDIA_TYPE

protected const val OCTET_MEDIA_TYPE: String = "application/octet-stream"
@Deprecated(
message = "Please use the capitalized constant `OCTET_MEDIA_TYPE` instead.",
replaceWith = ReplaceWith("OCTET_MEDIA_TYPE")
)
protected const val OctetMediaType: String = OCTET_MEDIA_TYPE

protected const val TEXT_MEDIA_TYPE: String = "text/plain"
@Deprecated(
message = "Please use the capitalized constant `TEXT_MEDIA_TYPE` instead.",
replaceWith = ReplaceWith("TEXT_MEDIA_TYPE")
)
protected const val TextMediaType: String = TEXT_MEDIA_TYPE

{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}const val BASE_URL_KEY: String = "{{packageName}}.baseUrl"
@Deprecated(
message = "Please use the capitalized constant `BASE_URL_KEY` instead.",
replaceWith = ReplaceWith("BASE_URL_KEY")
)
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}const val baseUrlKey: String = BASE_URL_KEY

{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val apiKey: MutableMap<String, String> = mutableMapOf()
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val apiKeyPrefix: MutableMap<String, String> = mutableMapOf()
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}var username: String? = null
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}var password: String? = null
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}var accessToken: String? = null
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}const val baseUrlKey: String = "{{packageName}}.baseUrl"

@JvmStatic
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val defaultClient: OkHttpClient by lazy {
Expand All @@ -98,7 +157,7 @@ import com.squareup.moshi.adapter
protected fun guessContentTypeFromByteArray(byteArray: ByteArray): String {
val contentType = try {
URLConnection.guessContentTypeFromStream(byteArray.inputStream())
} catch (io: IOException) {
} catch (_: IOException) {
"application/octet-stream"
}
return contentType
Expand Down Expand Up @@ -137,7 +196,7 @@ import com.squareup.moshi.adapter
/**
* Adds a File to a MultipartBody.Builder
* Defined a helper in the requestBody method to not duplicate code
* It will be used when the content is a FormDataMediaType and the body of the PartConfig is a File
* It will be used when the content is a `FORM_DATA_MEDIA_TYPE` and the body of the PartConfig is a File
*
* @param name The field name to add in the request
* @param headers The headers that are in the PartConfig
Expand Down Expand Up @@ -167,7 +226,7 @@ import com.squareup.moshi.adapter
if (serializer != null) {
return serializer(obj)
}

return if (contentType?.contains("json") == true) {
{{#moshi}}
Serializer.moshi.adapter(Any::class.java).toJson(obj)
Expand All @@ -191,7 +250,7 @@ import com.squareup.moshi.adapter
/**
* Adds any type to a MultipartBody.Builder
* Defined a helper in the requestBody method to not duplicate code
* It will be used when the content is a FormDataMediaType and the body of the PartConfig is not a File.
* It will be used when the content is a `FORM_DATA_MEDIA_TYPE` and the body of the PartConfig is not a File.
*
* @param name The field name to add in the request
* @param headers The headers that are in the PartConfig
Expand All @@ -214,7 +273,7 @@ import com.squareup.moshi.adapter
when {
content is ByteArray -> content.toRequestBody((mediaType ?: guessContentTypeFromByteArray(content)).toMediaTypeOrNull())
content is File -> content.asRequestBody((mediaType ?: guessContentTypeFromFile(content)).toMediaTypeOrNull())
mediaType == FormDataMediaType ->
mediaType == FORM_DATA_MEDIA_TYPE ->
MultipartBody.Builder()
.setType(MultipartBody.FORM)
.apply {
Expand All @@ -236,7 +295,7 @@ import com.squareup.moshi.adapter
}
}
}.build()
mediaType == FormUrlEncMediaType -> {
mediaType == FORM_URL_ENC_MEDIA_TYPE -> {
FormBody.Builder().apply {
// content's type *must* be Map<String, PartConfig<*>>
@Suppress("UNCHECKED_CAST")
Expand All @@ -261,23 +320,22 @@ import com.squareup.moshi.adapter
{{#kotlinx_serialization}}
Serializer.kotlinxSerializationJson.encodeToString(content)
{{/kotlinx_serialization}}
.toRequestBody((mediaType ?: JsonMediaType).toMediaTypeOrNull())
.toRequestBody((mediaType ?: JSON_MEDIA_TYPE).toMediaTypeOrNull())
}
mediaType == XmlMediaType -> throw UnsupportedOperationException("xml not currently supported.")
mediaType == TextMediaType && content is String ->
content.toRequestBody(TextMediaType.toMediaTypeOrNull())
mediaType == XML_MEDIA_TYPE -> throw UnsupportedOperationException("xml not currently supported.")
mediaType == TEXT_MEDIA_TYPE && content is String ->
content.toRequestBody(TEXT_MEDIA_TYPE.toMediaTypeOrNull())
// TODO: this should be extended with other serializers
else -> throw UnsupportedOperationException("requestBody currently only supports JSON body, text body, byte body and File body.")
}

{{#moshi}}
@OptIn(ExperimentalStdlibApi::class)
{{/moshi}}
protected inline fun <reified T: Any?> responseBody(response: Response, mediaType: String? = JsonMediaType): T? {
protected inline fun <reified T: Any?> responseBody(response: Response, mediaType: String? = JSON_MEDIA_TYPE): T? {
val body = response.body
if(body == null) {
return null
} else if (T::class.java == Unit::class.java) {

if (T::class.java == Unit::class.java) {
// No need to parse the body when we're not interested in the body
// Useful when API is returning other Content-Type
return null
Expand Down Expand Up @@ -352,8 +410,8 @@ import com.squareup.moshi.adapter
}}{{#jackson}}Serializer.jacksonObjectMapper.readValue(bodyContent, object: TypeReference<T>() {}){{/jackson}}{{!
}}{{#kotlinx_serialization}}Serializer.kotlinxSerializationJson.decodeFromString<T>(bodyContent){{/kotlinx_serialization}}
}
mediaType == OctetMediaType -> body.bytes() as? T
mediaType == TextMediaType -> body.string() as? T
mediaType == OCTET_MEDIA_TYPE -> body.bytes() as? T
mediaType == TEXT_MEDIA_TYPE -> body.string() as? T
else -> throw UnsupportedOperationException("responseBody currently only supports JSON body, text body and byte body.")
}
}
Expand Down Expand Up @@ -394,26 +452,26 @@ import com.squareup.moshi.adapter
{{/isApiKey}}
{{#isBasic}}
{{#isBasicBasic}}
if (requestConfig.headers[Authorization].isNullOrEmpty()) {
if (requestConfig.headers[AUTHORIZATION].isNullOrEmpty()) {
username?.let { username ->
password?.let { password ->
requestConfig.headers[Authorization] = okhttp3.Credentials.basic(username, password)
requestConfig.headers[AUTHORIZATION] = okhttp3.Credentials.basic(username, password)
}
}
}
{{/isBasicBasic}}
{{#isBasicBearer}}
if (requestConfig.headers[Authorization].isNullOrEmpty()) {
if (requestConfig.headers[AUTHORIZATION].isNullOrEmpty()) {
accessToken?.let { accessToken ->
requestConfig.headers[Authorization] = "Bearer $accessToken"
requestConfig.headers[AUTHORIZATION] = "Bearer $accessToken"
}
}
{{/isBasicBearer}}
{{/isBasic}}
{{#isOAuth}}
if (requestConfig.headers[Authorization].isNullOrEmpty()) {
if (requestConfig.headers[AUTHORIZATION].isNullOrEmpty()) {
accessToken?.let { accessToken ->
requestConfig.headers[Authorization] = "Bearer $accessToken "
requestConfig.headers[AUTHORIZATION] = "Bearer $accessToken "
}
}
{{/isOAuth}}
Expand All @@ -440,21 +498,21 @@ import com.squareup.moshi.adapter
}.build()

// take content-type/accept from spec or set to default (application/json) if not defined
if (requestConfig.body != null && requestConfig.headers[ContentType].isNullOrEmpty()) {
requestConfig.headers[ContentType] = JsonMediaType
if (requestConfig.body != null && requestConfig.headers[CONTENT_TYPE].isNullOrEmpty()) {
requestConfig.headers[CONTENT_TYPE] = JSON_MEDIA_TYPE
}
if (requestConfig.headers[Accept].isNullOrEmpty()) {
requestConfig.headers[Accept] = JsonMediaType
if (requestConfig.headers[ACCEPT].isNullOrEmpty()) {
requestConfig.headers[ACCEPT] = JSON_MEDIA_TYPE
}
val headers = requestConfig.headers

if (headers[Accept].isNullOrEmpty()) {
throw kotlin.IllegalStateException("Missing Accept header. This is required.")
if (headers[ACCEPT].isNullOrEmpty()) {
throw kotlin.IllegalStateException("Missing ACCEPT header. This is required.")
}

val contentType = if (headers[ContentType] != null) {
val contentType = if (headers[CONTENT_TYPE] != null) {
// TODO: support multiple contentType options here.
(headers[ContentType] as String).substringBefore(";").lowercase(Locale.US)
(headers[CONTENT_TYPE] as String).substringBefore(";").lowercase(Locale.US)
} else {
null
}
Expand Down Expand Up @@ -498,7 +556,7 @@ import com.squareup.moshi.adapter
val response = client.newCall(request).execute()
{{/useCoroutines}}

val accept = response.header(ContentType)?.substringBefore(";")?.lowercase(Locale.US)
val accept = response.header(CONTENT_TYPE)?.substringBefore(";")?.lowercase(Locale.US)

// TODO: handle specific mapping types. e.g. Map<int, Class<?>>
@Suppress("UNNECESSARY_SAFE_CALL")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -376,12 +376,16 @@ import okhttp3.MediaType.Companion.toMediaType
}

{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}companion object {
@JvmStatic
protected val baseUrlKey: String = "{{packageName}}.baseUrl"
protected const val BASE_URL_KEY: String = "{{packageName}}.baseUrl"
@Deprecated(
message = "Please use the capitalized constant `BASE_URL_KEY` instead.",
replaceWith = ReplaceWith("BASE_URL_KEY")
)
protected const val baseUrlKey: String = BASE_URL_KEY

@JvmStatic
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val defaultBasePath: String by lazy {
System.getProperties().getProperty(baseUrlKey, "{{{basePath}}}")
System.getProperties().getProperty(BASE_URL_KEY, "{{{basePath}}}")
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,16 @@ import com.google.gson.reflect.TypeToken

{{#nonPublicApi}}internal {{/nonPublicApi}}{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}open class ApiClient(val basePath: kotlin.String = defaultBasePath, val accessToken: String? = null, val apiKey: MutableMap<String, String> = mutableMapOf(), val apiKeyPrefix: MutableMap<String, String> = mutableMapOf(), var username: String? = null, var password: String? = null, val vertx: Vertx) {
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}companion object {
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}const val baseUrlKey: String = "{{packageName}}.baseUrl"
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}const val BASE_URL_KEY: String = "{{packageName}}.baseUrl"
@Deprecated(
message = "Please use the capitalized constant `BASE_URL_KEY` instead.",
replaceWith = ReplaceWith("BASE_URL_KEY")
)
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}const val baseUrlKey: String = BASE_URL_KEY

@JvmStatic
{{^nonPublicApi}}{{#explicitApi}}public {{/explicitApi}}{{/nonPublicApi}}val defaultBasePath: String by lazy {
System.getProperties().getProperty(baseUrlKey, "{{{basePath}}}")
System.getProperties().getProperty(BASE_URL_KEY, "{{{basePath}}}")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ open class AuthApi(basePath: kotlin.String = defaultBasePath, client: Call.Facto
companion object {
@JvmStatic
val defaultBasePath: String by lazy {
System.getProperties().getProperty(ApiClient.baseUrlKey, "http://localhost:3000")
System.getProperties().getProperty(ApiClient.BASE_URL_KEY, "http://localhost:3000")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ open class BodyApi(basePath: kotlin.String = defaultBasePath, client: Call.Facto
companion object {
@JvmStatic
val defaultBasePath: String by lazy {
System.getProperties().getProperty(ApiClient.baseUrlKey, "http://localhost:3000")
System.getProperties().getProperty(ApiClient.BASE_URL_KEY, "http://localhost:3000")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ open class FormApi(basePath: kotlin.String = defaultBasePath, client: Call.Facto
companion object {
@JvmStatic
val defaultBasePath: String by lazy {
System.getProperties().getProperty(ApiClient.baseUrlKey, "http://localhost:3000")
System.getProperties().getProperty(ApiClient.BASE_URL_KEY, "http://localhost:3000")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ open class HeaderApi(basePath: kotlin.String = defaultBasePath, client: Call.Fac
companion object {
@JvmStatic
val defaultBasePath: String by lazy {
System.getProperties().getProperty(ApiClient.baseUrlKey, "http://localhost:3000")
System.getProperties().getProperty(ApiClient.BASE_URL_KEY, "http://localhost:3000")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ open class PathApi(basePath: kotlin.String = defaultBasePath, client: Call.Facto
companion object {
@JvmStatic
val defaultBasePath: String by lazy {
System.getProperties().getProperty(ApiClient.baseUrlKey, "http://localhost:3000")
System.getProperties().getProperty(ApiClient.BASE_URL_KEY, "http://localhost:3000")
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ open class QueryApi(basePath: kotlin.String = defaultBasePath, client: Call.Fact
companion object {
@JvmStatic
val defaultBasePath: String by lazy {
System.getProperties().getProperty(ApiClient.baseUrlKey, "http://localhost:3000")
System.getProperties().getProperty(ApiClient.BASE_URL_KEY, "http://localhost:3000")
}
}

Expand Down
Loading
Loading