-
Notifications
You must be signed in to change notification settings - Fork 12
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
272 changed files
with
8,811 additions
and
12,237 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,20 +1,156 @@ | ||
# org.openapitools.client - Kotlin client library for Conekta API | ||
|
||
Conekta sdk | ||
|
||
## Overview | ||
This API client was generated by the [OpenAPI Generator](https://openapi-generator.tech) project. By using the [openapi-spec](https://github.com/OAI/OpenAPI-Specification) from a remote server, you can easily generate an API client. | ||
A kotlin client for Android using the currently recommended http client, Volley. See https://developer.android.com/training/volley | ||
|
||
- API version: 2.1.0 | ||
- Package version: | ||
- Generator version: 7.6.0 | ||
- Build package: org.openapitools.codegen.languages.KotlinClientCodegen | ||
For more information, please visit [https://github.com/conekta/openapi/issues](https://github.com/conekta/openapi/issues) | ||
- Currently sends GsonRequests | ||
- Currently only supports Gson as a serializer - will throw an exception if a different serializer is chosen | ||
- Defaults the source location to src/main/java as per standard Android builds | ||
|
||
|
||
## Design | ||
|
||
Volley is a queue/request based layer on top of http url stack specific to Android. Android favours dependency injection and | ||
a layered architecture, and IO performed off the main thread to maintain UI responsiveness, with a preferred technique of | ||
kotlin co-routines. The code gen library reflects these factors. | ||
|
||
- Api calls use co-routines, and execute them using volley callbacks to avoid tying up a thread. | ||
- Facilitate dependency injection, with default implementations available. | ||
- Generate a requestFactory that can be overridden | ||
- Allow the passing of the RequestFactory per tag (api client) or per operation (an extra parameter is created on operations with non-global security), with per operation auth overriding global security. | ||
- DI scoping of the Request Factory and pre-generated auth header factories allow for thread safe and secure setting of credentials. | ||
- Lazy header factories allow for refreshing tokens etc | ||
- Factoring of header factories to the Request Factory allow ambient provision of credentials. Code gen library is credential storage agnostic. | ||
- Header factories allow the merging of generated headers from open api spec with dynamically added headers | ||
|
||
- Injection of http url stack to allow custom http stacks. Default implementation is best practice singleton | ||
- Data classes used for serialisation to reflect volley's preference - an immutable request that once queued can't be tampered with. | ||
|
||
- Reuse model class and other jvm common infrastructure | ||
|
||
- Optional generation of room database models, and transform methods to these from open api models | ||
- Room and api models can be extended with additional extension properties. | ||
|
||
## Future improvements | ||
- Option to generate image requests on certain conditionals e.g content-type gif etc | ||
- Support for kotlin serialization. | ||
- Multi part form parameters and support for file inputs | ||
|
||
## Usage | ||
Hilt Dependency injection example - with default values for parameters overridden. | ||
``` | ||
@Provides | ||
internal fun provideSomeApi( | ||
context: Context, | ||
restService: IRestService, | ||
configurationService: IConfigurationService, | ||
sessionService: ISessionService | ||
): SomeApi { | ||
return SomeApi( | ||
context = context, | ||
requestQueue = restService.getRequestQueue(), | ||
requestFactory = RequestFactory(listOf(createSessionHeaderFactory(sessionService), createTraceHeaderFactory()), | ||
postProcessors = listOf(retryPolicySetter)), | ||
basePath = configurationService.getBaseUrl() | ||
) | ||
} | ||
``` | ||
Here is the constructor so you can see the defaults | ||
```class SomeApi ( | ||
val context: Context, | ||
val requestQueue: Lazy<RequestQueue> = lazy(initializer = { | ||
Volley.newRequestQueue(context.applicationContext) | ||
}), | ||
val requestFactory: IRequestFactory = RequestFactory(), | ||
val basePath: String = "https://yourbasepath.from_input_parameter.com/api", | ||
private val postProcessors :List <(Request<*>) -> Unit> = listOf()) { | ||
``` | ||
|
||
### Overriding defaults | ||
The above constructor for each api allows the following to be customized | ||
- A custom context, so either a singleton request queue or different scope can be created - see | ||
https://developer.android.com/training/volley/requestqueue#singleton | ||
- An overridable request queue - which in turn can have a custom http url stack passed to it | ||
- An overridable request factory constructor call, or a request factory that can be overridden by a custom template, with | ||
custom header factory, request post processors and custom gson adapters injected. | ||
|
||
#### Overriding request generation | ||
Request generation can be overridden by | ||
- Overriding the entire request factory template | ||
- Supplying custom header factories - methods that take any possible parameters but return a map of headers | ||
- Supplying custom request post processors - methods that take and return the request object | ||
|
||
Header factory examples can be found in the auth section, as these are implemented as header factories. eg | ||
``` | ||
val basicAuthHeaderFactoryBuilder = { username: String?, password: String? -> | ||
{ mapOf("Authorization" to "Basic " + Base64.encodeToString("${username ?: ""}:${password ?: ""}".toByteArray(), Base64.DEFAULT))} | ||
} | ||
``` | ||
In this case it's a lambda function (a factory method) that takes an username and password, and returns a map of headers. Other | ||
generated code will supply the username and password. In this case it results in a map of just one key/value pair, but | ||
it could be multiple. The important part is it's returning a map - and that the surrounding code | ||
will can bind the inputs to it at some point. | ||
|
||
Here is a different example that supplies tracing header values | ||
``` | ||
/** | ||
* Create a lambda of tracing headers to be injected into an API's [RequestFactory]. | ||
*/ | ||
private fun createTraceHeaderFactory(): () -> Map<String, String> = { | ||
mapOf( | ||
HttpHeaderType.b3_traceId.rawValue to UUIDExtensions.asTraceId(UUID.randomUUID()), | ||
HttpHeaderType.b3_spanId.rawValue to UUIDExtensions.asSpanId(UUID.randomUUID()), | ||
HttpHeaderType.b3_sampled.rawValue to "1" | ||
) | ||
} | ||
``` | ||
Finally a post processor example | ||
``` | ||
/** | ||
* Configure a [DefaultRetryPolicy] to be injected into the [RequestFactory] with a maximum number of retries of zero. | ||
*/ | ||
private val retryPolicySetter = { request: Request<*> -> | ||
Unit.apply { | ||
request.setRetryPolicy( | ||
DefaultRetryPolicy( | ||
RestService.DEFAULT_TIMEOUT_MS, | ||
0, | ||
DefaultRetryPolicy.DEFAULT_BACKOFF_MULT | ||
) | ||
) | ||
} | ||
} | ||
``` | ||
|
||
### Serialization | ||
#### Gson and Polymorphic types | ||
The GsonRequest object can be passed custom type adapters | ||
``` | ||
class GsonRequest<T>( | ||
method: Int, | ||
url: String, | ||
private val body: Any?, | ||
private val headers: Map<String, String>?, | ||
private val params: MutableMap<String, String>?, | ||
private val contentTypeForBody: String?, | ||
private val encodingForParams: String?, | ||
private val gsonAdapters: Map<Type, Object>?, | ||
private val type: Type, | ||
private val listener: Response.Listener<T>, | ||
errorListener: Response.ErrorListener | ||
) : Request<T>(method, url, errorListener) { | ||
val gsonBuilder: GsonBuilder = GsonBuilder() | ||
.registerTypeAdapter(OffsetDateTime::class.java, OffsetDateTimeAdapter()) | ||
.registerTypeAdapter(LocalDateTime::class.java, LocalDateTimeAdapter()) | ||
.registerTypeAdapter(LocalDate::class.java, LocalDateAdapter()) | ||
.registerTypeAdapter(ByteArray::class.java, ByteArrayAdapter()) | ||
``` | ||
## Requires | ||
|
||
* Kotlin 1.7.21 | ||
* Gradle 7.5 | ||
* Kotlin 1.4.30 | ||
* Gradle 6.8.3 | ||
|
||
## Build | ||
|
||
|
@@ -32,13 +168,6 @@ Then, run: | |
|
||
This runs all tests and packages the library. | ||
|
||
## Features/Implementation Notes | ||
|
||
* Supports JSON inputs/outputs, File inputs, and Form inputs. | ||
* Supports collection formats for query parameters: csv, tsv, ssv, pipes. | ||
* Some Kotlin and Java types are fully qualified to avoid conflicts with types defined in OpenAPI definitions. | ||
* Implementation of ApiClient is intended to reduce method counts, specifically to benefit Android targets. | ||
|
||
<a id="documentation-for-api-endpoints"></a> | ||
## Documentation for API Endpoints | ||
|
||
|
@@ -333,8 +462,3 @@ Authentication schemes defined for the API: | |
|
||
- **Type**: HTTP Bearer Token authentication | ||
|
||
|
||
|
||
## Author | ||
|
||
[email protected] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,60 +1,89 @@ | ||
group 'io.conekta' | ||
version '6.0.0-beta' | ||
|
||
wrapper { | ||
gradleVersion = '8.7' | ||
distributionUrl = "https://services.gradle.org/distributions/gradle-$gradleVersion-all.zip" | ||
} | ||
|
||
buildscript { | ||
ext.kotlin_version = '1.9.23' | ||
ext.spotless_version = "6.25.0" | ||
|
||
ext.kotlin_version = '1.5.20' | ||
ext.swagger_annotations_version = "1.6.2" | ||
ext.gson_version = "2.8.6" | ||
ext.volley_version = "1.2.0" | ||
ext.junit_version = "4.13.2" | ||
ext.robolectric_version = "4.5.1" | ||
ext.concurrent_unit_version = "0.4.6" | ||
|
||
repositories { | ||
maven { url "https://repo1.maven.org/maven2" } | ||
mavenLocal() | ||
google() | ||
maven { | ||
url 'https://dl.google.com/dl/android/maven2' | ||
} | ||
mavenCentral() | ||
} | ||
dependencies { | ||
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" | ||
classpath "com.diffplug.spotless:spotless-plugin-gradle:$spotless_version" | ||
classpath 'com.android.tools.build:gradle:7.4.2' | ||
} | ||
} | ||
|
||
apply plugin: 'kotlin' | ||
apply plugin: 'maven-publish' | ||
apply plugin: 'com.diffplug.spotless' | ||
|
||
repositories { | ||
maven { url "https://repo1.maven.org/maven2" } | ||
allprojects { | ||
repositories { | ||
google() | ||
mavenCentral() | ||
} | ||
} | ||
|
||
// Use spotless plugin to automatically format code, remove unused import, etc | ||
// To apply changes directly to the file, run `gradlew spotlessApply` | ||
// Ref: https://github.com/diffplug/spotless/tree/main/plugin-gradle | ||
spotless { | ||
// comment out below to run spotless as part of the `check` task | ||
enforceCheck false | ||
apply plugin: 'com.android.library' | ||
apply plugin: 'kotlin-android' | ||
|
||
format 'misc', { | ||
// define the files (e.g. '*.gradle', '*.md') to apply `misc` to | ||
target '.gitignore' | ||
|
||
// define the steps to apply to those files | ||
trimTrailingWhitespace() | ||
indentWithSpaces() // Takes an integer argument if you don't like 4 | ||
endWithNewline() | ||
android { | ||
compileSdkVersion 30 | ||
defaultConfig { | ||
minSdkVersion 21 | ||
targetSdkVersion 30 | ||
} | ||
kotlin { | ||
ktfmt() | ||
compileOptions { | ||
coreLibraryDesugaringEnabled true | ||
sourceCompatibility JavaVersion.VERSION_1_8 | ||
targetCompatibility JavaVersion.VERSION_1_8 | ||
} | ||
lintOptions { | ||
abortOnError false | ||
} | ||
|
||
// Rename the aar correctly | ||
libraryVariants.all { variant -> | ||
variant.outputs.all { output -> | ||
if (outputFile != null && outputFileName.endsWith('.aar')) { | ||
outputFileName = "${archivesBaseName}-${version}.aar" | ||
} | ||
} | ||
} | ||
} | ||
|
||
test { | ||
useJUnitPlatform() | ||
testOptions { | ||
unitTests.returnDefaultValues = true | ||
} | ||
} | ||
|
||
dependencies { | ||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version" | ||
implementation "com.google.code.gson:gson:2.10.1" | ||
implementation "com.squareup.okhttp3:okhttp:4.12.0" | ||
coreLibraryDesugaring 'com.android.tools:desugar_jdk_libs:1.1.5' | ||
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version" | ||
implementation "io.swagger:swagger-annotations:$swagger_annotations_version" | ||
implementation "com.google.code.gson:gson:$gson_version" | ||
implementation "com.android.volley:volley:${volley_version}" | ||
testImplementation "junit:junit:$junit_version" | ||
testImplementation "org.robolectric:robolectric:${robolectric_version}" | ||
testImplementation "net.jodah:concurrentunit:${concurrent_unit_version}" | ||
testImplementation "io.kotlintest:kotlintest-runner-junit5:3.4.2" | ||
testImplementation("io.mockk:mockk:1.12.0") | ||
} | ||
|
||
afterEvaluate { | ||
android.libraryVariants.all { variant -> | ||
def task = project.tasks.create "jar${variant.name.capitalize()}", Jar | ||
task.description = "Create jar artifact for ${variant.name}" | ||
task.dependsOn variant.javaCompile | ||
task.from variant.javaCompile.destinationDirectory | ||
task.destinationDirectory = project.file("${project.buildDir}/outputs/jar") | ||
task.archiveFileName = "${project.name}-${variant.baseName}-${version}.jar" | ||
artifacts.add('archives', task); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,7 +19,7 @@ | |
"scmConnection": "scm:git:[email protected]:conekta/conekta-android..git", | ||
"scmDeveloperConnection": "scm:git:[email protected]:conekta/conekta-android..git", | ||
"scmUrl": "https://github.com/conekta/conekta-android./tree/main", | ||
"library": "jvm-okhttp4", | ||
"library": "jvm-volley", | ||
"swagger1AnnotationLibrary": false, | ||
"javaxPackage": "javax", | ||
"disallowAdditionalPropertiesIfNotPresent": true, | ||
|
Oops, something went wrong.