Class Subscription

java.lang.Object
com.arc_e_tect.gradle.apionly.subscriber.Subscription

public abstract class Subscription extends Object
One subscribed contract: which target, at which version, landing where.

Created through ApiOnlySubscriberExtension.subscribe(String, org.gradle.api.Action):


 apiOnlySubscriber {
     subscribe('customer-orders') {
         version = '2.1.0'
     }
 }
 

The version is declared per target rather than per channel, because each target is versioned independently. A change confined to one service's fragments must not oblige every other service to take a new version.

Each subscription registers a fetchApiSpec<Target> and a verifyApiSpec<Target> task, and contributes to the aggregate fetchApiSpec and verifyApiSpec tasks.

See Also:
  • Constructor Summary

    Constructors
    Constructor
    Description
    Subscription(String target, org.gradle.api.model.ObjectFactory objects)
    Creates a subscription for one target.
  • Method Summary

    Modifier and Type
    Method
    Description
    void
    channel(org.gradle.api.Action<? super ChannelSpec> action)
    Configures a channel of this subscription's own.
    abstract org.gradle.api.provider.Property<Boolean>
    Whether this subscription may resolve a pre-release contract.
    abstract org.gradle.api.provider.Property<String>
    The version of this target's contract to build against.
    abstract org.gradle.api.provider.Property<String>
    Overrides the artifact name this target is published under.
    org.gradle.api.provider.Provider<org.gradle.api.file.RegularFile>
    The fetched AsyncAPI document.
    The channel this subscription resolves through.
    abstract org.gradle.api.provider.Property<String>
    Overrides ChannelSpec.getGroupId() for this one target.
    abstract org.gradle.api.file.DirectoryProperty
    Where the fetched documents land.
    The name this subscription is keyed by in its container.
    org.gradle.api.provider.Provider<org.gradle.api.file.RegularFile>
    The fetched OpenAPI document.
    The contract this subscription is for.
    boolean
    Whether this subscription is for an API the project calls, rather than for the contract it implements.
    void
    setVersion(Object version)
    Refuses the property's old name.

    Methods inherited from class java.lang.Object

    clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
  • Constructor Details

    • Subscription

      @Inject public Subscription(String target, org.gradle.api.model.ObjectFactory objects)
      Creates a subscription for one target.

      Gradle instantiates this through its object factory; build scripts call ApiOnlySubscriberExtension.subscribe(String, org.gradle.api.Action) rather than constructing one directly.

      Parameters:
      target - the contract this subscription is for, which is also the element's name within the container
      objects - Gradle's object factory, supplied by injection
  • Method Details

    • getName

      public String getName()
      The name this subscription is keyed by in its container.

      Gradle's NamedDomainObjectContainer requires it; here it is always the target name, so this and getTarget() agree.

      Returns:
      the target name
    • getTarget

      public String getTarget()
      The contract this subscription is for.
      Returns:
      the target name, the same value as getName()
    • isClient

      public boolean isClient()
      Whether this subscription is for an API the project calls, rather than for the contract it implements.

      Fixed when the subscription is declared: by ApiOnlySubscriberExtension.subscribeAsClient(String, org.gradle.api.Action) for an API the project calls, and by ApiOnlySubscriberExtension.subscribe(String, org.gradle.api.Action) for the contract it implements.

      Returns:
      true for an API this project calls
    • getApiContractVersion

      public abstract org.gradle.api.provider.Property<String> getApiContractVersion()
      The version of this target's contract to build against.

      Defaults to ApiOnlySubscriberExtension.getApiContractVersion(), which in turn defaults to the apiContractVersion project property; one of the three must be set. -PapiContractVersion=... on the command line overrides all three for the contract the project implements. A pre-release version is refused unless getAllowPrerelease() is set.

      A subscription for an API the project calls has no default, sets its own, and is not overridden from the command line: the project's apiContractVersion is the version of the contract it implements.

      Returns:
      the version to resolve
    • setVersion

      public void setVersion(Object version)
      Refuses the property's old name. Without it, a build script that still sets version on a subscription would set the project's own version instead, silently.
      Parameters:
      version - ignored
      Throws:
      org.gradle.api.GradleException - always, naming the new property
    • getGroupId

      public abstract org.gradle.api.provider.Property<String> getGroupId()
      Overrides ChannelSpec.getGroupId() for this one target.

      Useful when most contracts come from one group but a particular target is published elsewhere.

      Returns:
      the group id for this target; unset, meaning the channel's applies
    • getArtifactId

      public abstract org.gradle.api.provider.Property<String> getArtifactId()
      Overrides the artifact name this target is published under.
      Returns:
      the artifact id; defaults to the target name
    • getAllowPrerelease

      public abstract org.gradle.api.provider.Property<Boolean> getAllowPrerelease()
      Whether this subscription may resolve a pre-release contract.

      False by default, and deliberately. API-Only design means implementation begins against a contract that is not finished, so pre-releases must exist — but a pre-release must never quietly satisfy a build that did not ask for one. Opting in is a visible, reviewable line in a build file:

      
       subscribe('customer-orders') {
           version = '2.1.0-rc.1'
           allowPrerelease = true
       }
       

      Both the SemVer spelling (-rc.1, -alpha.3) and Maven's -SNAPSHOT count as pre-releases.

      Returns:
      whether a pre-release may be resolved; defaults to false
    • getInto

      public abstract org.gradle.api.file.DirectoryProperty getInto()
      Where the fetched documents land.

      Defaults to build/api-spec/<target>/ rather than src/main/resources. Generated files inside a source tree show up in IDE search, tempt hand-editing, and survive a clean. From build/ they reach the classpath identically, because the plugin registers this directory as an additional resources source directory.

      Writing into src/ remains possible for teams whose tooling insists on it; it is simply not the default.

      For an API the project calls, the directory is not a resources directory itself: its contents are copied to contracts/<target>/ on the classpath, so that the root stays the implemented contract's.

      Returns:
      the directory fetched documents are unpacked into
    • getChannel

      public ChannelSpec getChannel()
      The channel this subscription resolves through.

      Every setting this subscription does not set comes from the project's channel, so a subscription states only what differs: an API the project calls, published to a Maven repository, next to a contract the project takes from a file channel, or the other way round.

      Returns:
      this subscription's channel specification
    • channel

      public void channel(org.gradle.api.Action<? super ChannelSpec> action)
      Configures a channel of this subscription's own.
      
       subscribeAsClient('order-payments') {
           version = '1.4.0'
           channel {
               type = 'maven'
               groupId = 'com.example.payments'
           }
       }
       
      Parameters:
      action - configuration applied to this subscription's channel
    • getOpenapi

      public org.gradle.api.provider.Provider<org.gradle.api.file.RegularFile> getOpenapi()
      The fetched OpenAPI document.

      Wire this into whatever validates against the contract, and the dependency on the fetch travels with it:

      
       openApiGenerate {
           inputSpec = apiOnlySubscriber.subscription('customer-orders').openapi.map { it.asFile.path }
       }
       
      Returns:
      a provider for openapi.yaml inside getInto(), carrying a dependency on the fetch task
      Throws:
      IllegalStateException - if read before the plugin has registered the fetch task, which cannot happen from a build script
    • getAsyncapi

      public org.gradle.api.provider.Provider<org.gradle.api.file.RegularFile> getAsyncapi()
      The fetched AsyncAPI document.
      Returns:
      a provider for asyncapi.yaml inside getInto(), carrying a dependency on the fetch task
      Throws:
      IllegalStateException - if read before the plugin has registered the fetch task, which cannot happen from a build script
      See Also: