We use a library we made ourselves to convert www-...
# kotlinx-html
c
We use a library we made ourselves to convert www-url-encoded form submits to a Jackson-internal representation of JSON, which Jackson can the type coerce into a data class that we call a
FormDto
. The library sets a standard for the names (the
name
attribute on HTML form fields) so they can be used to provide a structure to the data.
a
Ah, right... We're kind of pursuing something similar, but I've written so much reflection to make it work it feels really dirty. But using JSON as an intermediary might be a way to skip the reflection. I might have to test that idea. We are trying to use javax.validation as well as the reflection for binding to objects. Looked into Konform, but there is no way to "use" the validations. Example: We add validation info to the <input> fields based on the javax.validation annotations (NotEmpty, Size, etc). Might see if that is possible with Akkurate. So the validation, the object structure and the (ugly) reflection based binding all align with a 'myObj.subObj.aList[1].finalProp' pattern and then automatically showing the field error with the field.
c
we built a tiny function to do that
here an example:
image.png
this is the implementation:
image.png
here a wilder example `
Copy code
name =
  toNameString(ShowTicketsFormDto::ticketGroups, index, TicketGroupDto::id)
`
Our
*FormDto
data classes have the
validate()
method on them, decaratively implemented with Konform. If we need more than one way to validate its very easy to just make more and abstract common bits.
i'd be willing to share the converter lib with you
(www-url-encoded pairs to Jackson internals representation)
i really hate annotation based validation, i prefer "real code", hence Kotlin on the JVM is God-sent
a
Awesome! Thanks for sharing. I'd love to see the converter too. Hope to share the stuff I end up with, but no guarantee. 🙂 I definitely prefer code over annotations in general too, but for validations I find that it is pretty good. You still won't be able to generate attributes for the input field with Konform though? It's not a make or break requirement on our side, but I really enjoy how smooth feedback and navigation is with proper constraints on the input fields.
c
"You still won't be able to generate attributes for the input field with Konform though?" -> we wrap most form fields in a bit of code, so a kotlinx.html
select
becomes a
validatedSelect
which we pass the Konform
ValidationResult
a
Right, but that is the output of the validation? Not that the input field should have minlength=3?
c
so probably not as smooth.. can you give an example bit of code showing who smooth that works for you now? (is that with or w/o kotlinxhtml?)
"Right, but that is the output of the validation? Not that the input field should have minlength=3" -> exactly, we dont want any validation feedback until submit is hit. this is a common UX pattern (only validate once submitted)
maybe we can work it into a library if we can abstract the bit that we both do different, maybe not (either way im fine with it -- it's pretty simple and heavily tested)
do you have an email (maybe in a DM) for me?
a
Right now we are using the HTML (in addition, so both). I like how it works, but I can totally see that we might have to disable it down the line. Here's our annotation based (hack):
Copy code
fun LABEL.inputWithConstraints(
        path: String,
        existingValue: String?,
        inputType: InputType,
        property: KProperty1<Any, String>
    ) {
        input(inputType) {
            name = path
            value = existingValue ?: ""
            property.javaAnnotations().forEach {
                when (it) {
                    is Size -> {
                        minLength = it.min.toString()
                        maxLength = it.max.toString()
                    }

                    is Max -> max = it.value.toString()
                    is NotNull -> required = true
                    is NotEmpty -> required = true
                    else -> if (property.isRequired()) required = true // Should we do this? Maybe just rely on the annotations? Maybe fail fast?
                }
            }
        }
    }
(the javaAnnotations() extension method is custom helper))
Yeah, I might have time to work on that over the summer. The binding could possibly be separate from the rest so at least that is shareable. I'll pop you my mail in a DM. 🙂
Oh yeah, and the .isRequired() is a hack to check for nullable as well, so hence the comment about maybe skipping
c
i dont think this is possible with konform as the contstraints are never exposed as "data" (in ouir code, maybe it's possible but we just dont use it that way)
👍 1