Skip to content

Commit 3ee0155

Browse files
Adam/remove retrofit (#602)
* Update OpenAPI config to use Okhttp instead of Retrofit * Generate new OkHttp based code for REST API * Exclude the whole /restapi directory from detekt * Use new services without the Retrofit dependencies
1 parent 1e19b87 commit 3ee0155

34 files changed

+1936
-518
lines changed

build-logic/convention/src/main/kotlin/GravatarOpenApiGeneratorConventionPlugin.kt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,13 @@ class GravatarOpenApiGeneratorConventionPlugin : Plugin<Project> {
2323
// Set the generation configuration options
2424
configOptions.set(
2525
mapOf(
26-
"library" to "jvm-retrofit2",
26+
"library" to "jvm-okhttp4",
2727
"serializationLibrary" to "moshi",
2828
"groupId" to "com.gravatar",
2929
"packageName" to "com.gravatar.restapi",
3030
"useCoroutines" to "true",
3131
"moshiCodeGen" to "true",
32+
"supportAndroidApiLevel25AndBelow" to "true",
3233
),
3334
)
3435
importMappings.set(
@@ -49,6 +50,8 @@ class GravatarOpenApiGeneratorConventionPlugin : Plugin<Project> {
4950
mapOf(
5051
"apis" to "",
5152
"models" to "",
53+
"supportingFiles" to "ApiClient.kt,ApiAbstractions.kt,Serializer.kt,ApiResponse.kt," +
54+
"Serializer.kt,PartConfig.kt,RequestConfig.kt,RequestMethod.kt,URIAdapter.kt",
5255
),
5356
)
5457
}

config/detekt/detekt.yml

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -9,14 +9,12 @@ complexity:
99
LongParameterList:
1010
ignoreDefaultParameters: true
1111
ignoreAnnotated: ['Inject', 'Composable']
12-
excludes: [ '**/restapi/models/**' ]
1312
LongMethod:
1413
ignoreAnnotated: ['Composable']
1514
TooManyFunctions:
1615
active: false
1716
CyclomaticComplexMethod:
1817
ignoreSimpleWhenEntries: true
19-
excludes: [ '**/restapi/models/**' ]
2018

2119
coroutines:
2220
GlobalCoroutineUsage:
@@ -27,7 +25,6 @@ naming:
2725
ignoreAnnotated: ['Composable']
2826
FunctionParameterNaming:
2927
active: true
30-
excludes: [ '**/restapi/**' ]
3128

3229
style:
3330
DataClassShouldBeImmutable:
@@ -48,7 +45,6 @@ style:
4845
MaxLineLength:
4946
active: true
5047
maxLineLength: 120
51-
excludes: [ '**/api/**', '**/restapi/**' ]
5248
excludePackageStatements: true
5349
excludeImportStatements: true
5450
excludeCommentStatements: false
@@ -57,7 +53,7 @@ style:
5753
comments:
5854
UndocumentedPublicClass:
5955
active: true
60-
excludes: [ '**/test/**', '**/androidTest/**', '**/demoapp/**', '**/restapi/models/**', '**/uitestutils/**' ]
56+
excludes: [ '**/test/**', '**/androidTest/**', '**/demoapp/**', '**/uitestutils/**' ]
6157
searchInNestedClass: true
6258
searchInInnerClass: true
6359
searchInInnerObject: true
@@ -68,16 +64,16 @@ comments:
6864
# Ignore Jetpack Compose functions annotated with @Preview
6965
ignoreAnnotated:
7066
- 'Preview'
71-
excludes: [ '**/test/**', '**/androidTest/**', '**/demoapp/**', '**/restapi/models/**', '**/uitestutils/**' ]
67+
excludes: [ '**/test/**', '**/androidTest/**', '**/demoapp/**', '**/uitestutils/**' ]
7268
searchProtectedFunction: false
7369
UndocumentedPublicProperty:
7470
active: true
7571
# TODO - Remove the explicit exclusion of Email.kt once we implement the new REST API
76-
excludes: [ '**/test/**', '**/androidTest/**', '**/demoapp/**', '**/restapi/models/**', '**/uitestutils/**' ]
72+
excludes: [ '**/test/**', '**/androidTest/**', '**/demoapp/**', '**/uitestutils/**' ]
7773
searchProtectedProperty: false
7874
OutdatedDocumentation:
7975
active: true
80-
excludes: [ '**/test/**', '**/androidTest/**', '**/demoapp/**', '**/restapi/models/**', '**/restapi/apis/**' ]
76+
excludes: [ '**/test/**', '**/androidTest/**', '**/demoapp/**' ]
8177
matchTypeParameters: true
8278
matchDeclarationsOrder: true
8379
allowParamOnConstructorProperties: false

gradle/libs.versions.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ kotlinx-coroutines-test = { group = "org.jetbrains.kotlinx", name = "kotlinx-cor
7070
mockk-agent = { group = "io.mockk", name = "mockk-agent", version.ref = "mockk" }
7171
mockk-android = { group = "io.mockk", name = "mockk-android", version.ref = "mockk" }
7272
mockwebserver = { group = "com.squareup.okhttp3", name = "mockwebserver", version.ref = "mockwebserver" }
73+
moshi = { group = "com.squareup.moshi", name = "moshi", version.ref = "moshi" }
7374
moshi-kotlin-codegen = { group = "com.squareup.moshi", name = "moshi-kotlin-codegen", version.ref = "moshi" }
7475
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okhttp" }
7576
retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version.ref = "retrofit" }

gravatar/build.gradle.kts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,17 @@ android {
3232
}
3333
}
3434
}
35+
36+
detekt {
37+
tasks.withType<io.gitlab.arturbosch.detekt.Detekt>().configureEach {
38+
exclude("**/restapi/**") // Specify the directory to exclude
39+
}
40+
}
3541
}
3642

3743
dependencies {
3844
api(libs.okhttp)
39-
implementation(libs.retrofit)
40-
implementation(libs.retrofit.moshi.converter)
45+
implementation(libs.moshi)
4146
implementation(libs.kotlinx.coroutines)
4247
ksp(libs.moshi.kotlin.codegen)
4348

gravatar/openapi/api-gravatar.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -967,14 +967,14 @@
967967
"schema": {
968968
"type": "object",
969969
"properties": {
970-
"data": {
970+
"image": {
971971
"type": "string",
972972
"format": "binary",
973973
"description": "The avatar image file"
974974
}
975975
},
976976
"required": [
977-
"data"
977+
"image"
978978
]
979979
}
980980
}
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
package {{packageName}}.infrastructure
2+
3+
internal typealias MultiValueMap = MutableMap<String,List<String>>
4+
5+
internal fun collectionDelimiter(collectionFormat: String): String = when(collectionFormat) {
6+
"csv" -> ","
7+
"tsv" -> "\t"
8+
"pipe" -> "|"
9+
"space" -> " "
10+
else -> ""
11+
}
12+
13+
internal val defaultMultiValueConverter: (item: Any?) -> String = { item -> "$item" }
14+
15+
internal fun <T : Any?> toMultiValue(items: Array<T>, collectionFormat: String, map: (item: T) -> String = defaultMultiValueConverter): List<String>
16+
= toMultiValue(items.asIterable(), collectionFormat, map)
17+
18+
internal fun <T : Any?> toMultiValue(items: Iterable<T>, collectionFormat: String, map: (item: T) -> String = defaultMultiValueConverter): List<String> {
19+
return when(collectionFormat) {
20+
"multi" -> items.map(map)
21+
else -> listOf(items.joinToString(separator = collectionDelimiter(collectionFormat), transform = map))
22+
}
23+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package {{packageName}}.infrastructure
2+
3+
/**
4+
* Defines a config object for a given part of a multi-part request.
5+
* NOTE: Headers is a Map<String,String> because rfc2616 defines
6+
* multi-valued headers as csv-only.
7+
*/
8+
internal data class PartConfig<T>(
9+
val headers: MutableMap<String, String> = mutableMapOf(),
10+
val body: T? = null
11+
)
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
package {{packageName}}.infrastructure
2+
3+
/**
4+
* Defines a config object for a given request.
5+
* NOTE: This object doesn't include 'body' because it
6+
* allows for caching of the constructed object
7+
* for many request definitions.
8+
* NOTE: Headers is a Map<String,String> because rfc2616 defines
9+
* multi-valued headers as csv-only.
10+
*/
11+
internal data class RequestConfig<T>(
12+
val method: RequestMethod,
13+
val path: String,
14+
val headers: MutableMap<String, String> = mutableMapOf(),
15+
val params: MutableMap<String, Any> = mutableMapOf(),
16+
val query: MutableMap<String, List<String>> = mutableMapOf(),
17+
val requiresAuthentication: Boolean,
18+
val body: T? = null
19+
)
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package {{packageName}}.infrastructure
2+
3+
/**
4+
* Provides enumerated HTTP verbs
5+
*/
6+
internal enum class RequestMethod {
7+
GET, DELETE, HEAD, OPTIONS, PATCH, POST, PUT
8+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package {{packageName}}.infrastructure
2+
3+
{{#moshi}}
4+
import com.squareup.moshi.Moshi
5+
{{#enumUnknownDefaultCase}}
6+
import com.squareup.moshi.adapters.EnumJsonAdapter
7+
{{/enumUnknownDefaultCase}}
8+
{{^moshiCodeGen}}
9+
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
10+
{{/moshiCodeGen}}
11+
{{/moshi}}
12+
13+
internal object Serializer {
14+
{{#moshi}}
15+
@JvmStatic
16+
internal val moshiBuilder: Moshi.Builder = Moshi.Builder()
17+
.add(URIAdapter())
18+
{{^moshiCodeGen}}
19+
.add(KotlinJsonAdapterFactory())
20+
{{/moshiCodeGen}}
21+
22+
@JvmStatic
23+
internal val moshi: Moshi by lazy {
24+
{{#enumUnknownDefaultCase}}
25+
SerializerHelper.addEnumUnknownDefaultCase(moshiBuilder)
26+
{{/enumUnknownDefaultCase}}
27+
moshiBuilder.build()
28+
}
29+
{{/moshi}}
30+
}

0 commit comments

Comments
 (0)