Repository navigation
Add a Kotlin + Ktor example - #14
Merged
Merged
Conversation
This file contains hidden or 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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A tenth example: the same Hosted Fields payment on Kotlin + Ktor, built with Gradle.
The server half is 1:1 with
go-js— the same routes underBASE_PATH, the same OAuth 1.0aRSA-SHA256 signing, the same doubly-checked 3DS return, the same log redaction. The browser half
is
shared/, copied in byscripts/sync-shared.shlike every other plain-JS example.Port
3009, prefix/hosted-fields-examples-kotlin, e2e port4021.What it demonstrates that the other JVM example does not
Two dependencies, and one of them is the subject: Ktor, and kotlinx.serialization because the JVM
has no JSON of its own. Everything the integration itself needs is in the JDK —
java.net.httpcalls the gateway,
java.securitysigns. Four things Ktor makes easy to get wrong, each handledand commented where it is enforced:
prefix answers a
301from a route of its own — the redirect Go's mux and Tomcat send for free,and what the pages' relative asset URLs resolve against.
IgnoreTrailingSlashis deliberatelynot installed;
AutoHeadResponseis.staticResourcesis never installed.public/goes out through a four-name allowlist, thecounterpart of
spring.web.resources.add-mappings=falseand Sinatra'sstatic.withContext(Dispatchers.IO).java.net.http'ssendisblocking and a Ktor handler runs on a Netty event-loop thread.
URLEncoder.encodeorencodeURLParameter.Paynet.formEncodeisURLEncoder, because the body really is formencoded, and the 3DS callback is parsed off the body by hand.
One thing worth a second look
gradle/wrapper/gradle-wrapper.jaris the first binary in this repository. Gradle has noscript-only wrapper the way Maven's
distributionType=only-scriptis, and the alternative wasasking every reader to install Gradle first. It is mitigated rather than waved through: the
distribution is pinned by SHA-256 in
gradle-wrapper.properties, and CI runsgradle/actions/wrapper-validationover the jar. Both READMEs say so.Checks run locally
./scripts/sync-shared.sh && git diff --exit-code— clean./gradlew ktlintCheck build buildFatJarfrom cold — 11 tests, on the same cross-languagevectors as the other examples
npm run test:kotlin— 10 e2e specs, including the full 3DS round tripnpm run test:docker:kotlin— the same 10 against the container, which is what exercises theshipped
deploy/nginx.confnpm run test:docker:go— to confirm the compose stack is still intact with a tenth service in it