ermadmi78 / kobby

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

Ability to configure access to the context from the entity interface #20

Closed ermadmi78 closed 2 years ago

ermadmi78 commented 2 years ago

The generated entity interface implements the context interface to provide access to GraphQL query building functionality. For example the entity interface Film generated by tutorial schema looks like following:

public interface Film : CinemaContext {
  public val id: Long
  public val title: String
  public val actors: List<Actor>

  public override suspend fun query(__projection: QueryProjection.() -> Unit): Query
  public override suspend fun mutation(__projection: MutationProjection.() -> Unit): Mutation
  public override fun subscription(__projection: SubscriptionProjection.() -> Unit): 
    CinemaSubscriber<Subscription>
}

As you can see, the entity interface Film extends the context interface CinemaContext, which makes the entity an entry point for executing GraphQL queries. We can use Kotlin extension functions to create a smart API that looks like rich domain model. But the Kotlin extension functions defined in the context interface scope are available in the entity interface scope because the entity interface extends the context interface. Thus, context inheritance often leads to confusion in the customized API. To avoid such problems, we need to abandon context inheritance in the entity interface in favor of an accessor for the context.

Our entity interface might look like this:

public interface Film {
  public val id: Long
  public val title: String
  public val actors: List<Actor>

  public fun __context(): CinemaContext
}

But such a change would break the backward compatibility of the entity interfaces. Let's add the following generation settings to maintain backward compatibility:

plugins {
    kotlin("jvm")
    id("io.github.ermadmi78.kobby")
}

kobby {
    kotlin {
        entity {
            // Inherit context interface in entity interface
            contextInheritanceEnabled = true // true by default

            // Generate context access function
            contextFunEnabled = false // false by default

            // Context access function name
            contextFunName = "__context"
        }
    }
}
ermadmi78 commented 2 years ago

Available since version 1.4.0

To switch from context inheritance to context function:

Gradle

plugins {
    id("io.github.ermadmi78.kobby") version "1.4.0"
}

kobby {
    kotlin {
        entity {
            contextInheritanceEnabled = false
            contextFunEnabled = true
        }
    }
}

Maven

    <build>
        <plugins>
            <plugin>
                <groupId>io.github.ermadmi78</groupId>
                <artifactId>kobby-maven-plugin</artifactId>
                <version>1.4.0</version>
                <executions>
                    <execution>
                        <phase>generate-sources</phase>
                        <goals>
                            <goal>generate-kotlin</goal>
                        </goals>
                        <configuration>
                            <kotlin>
                                <entity>
                                    <contextInheritanceEnabled>false</contextInheritanceEnabled>
                                    <contextFunEnabled>true</contextFunEnabled>
                                </entity>
                            </kotlin>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>