Kobby is a codegen plugin of Kotlin DSL Client by GraphQL schema. The generated DSL supports execution of complex GraphQL queries, mutation and subscriptions in Kotlin with syntax similar to native GraphQL syntax.
Apache License 2.0
83
stars
4
forks
source link
Generate extension functions toBuilder, toDto, and toInput for DTO classes #37
The DTO and Input classes generated by Kobby contain helper builder classes that make it easy to create instances of these classes manually. The purpose of this issue is to extend the use of builder classes.
DTO classes refactoring
For GraphQL type Actor:
type Actor {
id: ID!
firstName: String!
lastName: String
}
Kobby generates a DTO class that looks like this:
public data class ActorDto(
public val id: Long? = null,
public val firstName: String? = null,
public val lastName: String? = null,
)
public fun ActorDto(block: ActorDtoBuilder.() -> Unit): ActorDto {
// ActorDto builder DSL
return ActorDtoBuilder().apply(block).let {
ActorDto(
it.id,
it.firstName,
it.lastName
)
}
}
public fun ActorDto.copy(block: ActorDtoBuilder.() -> Unit): ActorDto {
// ActorDto copy DSL
return ActorDtoBuilder().also {
it.id = this.id
it.firstName = this.firstName
it.lastName = this.lastName
}
.apply(block).let {
ActorDto(
it.id,
it.firstName,
it.lastName
)
}
}
public class ActorDtoBuilder {
public var id: Long? = null
public var firstName: String? = null
public var lastName: String? = null
}
Let's add the toBuilder and toDto extension functions to the generated DTO class, which will make the builder easier to use:
public data class ActorDto(
public val id: Long? = null,
public val firstName: String? = null,
public val lastName: String? = null,
)
public fun ActorDto.toBuilder(): ActorDtoBuilder = ActorDtoBuilder().also {
it.id = this.id
it.firstName = this.firstName
it.lastName = this.lastName
}
public fun ActorDtoBuilder.toDto(): ActorDto = ActorDto(
id,
firstName,
lastName
)
public fun ActorDto(block: ActorDtoBuilder.() -> Unit): ActorDto =
ActorDtoBuilder().apply(block).toDto()
public fun ActorDto.copy(block: ActorDtoBuilder.() -> Unit): ActorDto =
toBuilder().apply(block).toDto()
public class ActorDtoBuilder {
public var id: Long? = null
public var firstName: String? = null
public var lastName: String? = null
}
Kobby generates an Input class that looks like this:
public data class ActorInput(
public val id: Long,
public val firstName: String,
public val lastName: String? = null,
)
public fun ActorInput(block: ActorInputBuilder.() -> Unit): ActorInput {
// ActorInput builder DSL
return ActorInputBuilder().apply(block).let {
ActorInput(
it.id ?: error("ActorInput: 'id' must not be null"),
it.firstName ?: error("ActorInput: 'firstName' must not be null"),
it.lastName
)
}
}
public fun ActorInput.copy(block: ActorInputBuilder.() -> Unit): ActorInput {
// ActorInput copy DSL
return ActorInputBuilder().also {
it.id = this.id
it.firstName = this.firstName
it.lastName = this.lastName
}
.apply(block).let {
ActorInput(
it.id ?: error("ActorInput: 'id' must not be null"),
it.firstName ?: error("ActorInput: 'firstName' must not be null"),
it.lastName
)
}
}
public class ActorInputBuilder {
public var id: Long? = null
public var firstName: String? = null
public var lastName: String? = null
}
Let's add the toBuilder and toInput extension functions to the generated Input class, which will make the builder easier to use:
public data class ActorInput(
public val id: Long,
public val firstName: String,
public val lastName: String? = null,
)
public fun ActorInput.toBuilder(): ActorInputBuilder = ActorInputBuilder().also {
it.id = this.id
it.firstName = this.firstName
it.lastName = this.lastName
}
public fun ActorInputBuilder.toInput(): ActorInput = ActorInput(
id ?: error("ActorInput: 'id' must not be null"),
firstName ?: error("ActorInput: 'firstName' must not be null"),
lastName
)
public fun ActorInput(block: ActorInputBuilder.() -> Unit): ActorInput =
ActorInputBuilder().apply(block).toInput()
public fun ActorInput.copy(block: ActorInputBuilder.() -> Unit): ActorInput =
toBuilder().apply(block).toInput()
public class ActorInputBuilder {
public var id: Long? = null
public var firstName: String? = null
public var lastName: String? = null
}
Customization
Use the following build script blocks to customize extension function names.
Gradle:
plugins {
id("io.github.ermadmi78.kobby")
}
kobby {
kotlin {
dto {
builder {
// Name of DTO based "toBuilder" function for DTO classes
toBuilderFun = "toBuilder"
// Name of builder based "toDto" function for DTO classes
toDtoFun = "toDto"
// Name of builder based "toInput" function for DTO input classes
toInputFun = "toInput"
}
}
}
}
Maven:
<build>
<plugins>
<plugin>
<groupId>io.github.ermadmi78</groupId>
<artifactId>kobby-maven-plugin</artifactId>
<version>${kobby.version}</version>
<executions>
<execution>
<phase>generate-sources</phase>
<goals>
<goal>generate-kotlin</goal>
</goals>
<configuration>
<kotlin>
<dto>
<builder>
<!-- Name of DTO based "toBuilder" function for DTO classes -->
<toBuilderFun>toBuilder</toBuilderFun>
<!-- Name of builder based "toDto" function for DTO classes -->
<toDtoFun>toDto</toDtoFun>
<!-- Name of builder based "toInput" function for DTO input classes -->
<toInputFun>toInput</toInputFun>
</builder>
</dto>
</kotlin>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
The DTO and Input classes generated by Kobby contain helper builder classes that make it easy to create instances of these classes manually. The purpose of this issue is to extend the use of builder classes.
DTO classes refactoring
For GraphQL type
Actor
:Kobby generates a DTO class that looks like this:
Let's add the
toBuilder
andtoDto
extension functions to the generated DTO class, which will make the builder easier to use:Input classes refactoring
For GraphQL input
ActorInput
:Kobby generates an Input class that looks like this:
Let's add the
toBuilder
andtoInput
extension functions to the generated Input class, which will make the builder easier to use:Customization
Use the following build script blocks to customize extension function names.
Gradle:
Maven: