Skip to content

The Kotlin/JVM SDK for accessing various Merge Unified APIs

License

Notifications You must be signed in to change notification settings

merge-api/merge-sdk-kotlin

Repository files navigation

Deprecation Notice

Merge has released a new version of our Java SDK. As part of that release, we are providing a deprecation notice of our legacy SDKs.

To help give you time to plan your migration to our latest SDK:

  • August 2023: SDK deprecation notice on our legacy Java SDKs.
  • Until February 2024: we’ll support updates as needed and address bugs in priority order
  • After February 2024: we’ll no longer make updates or bug fixes to the deprecated SDKs

For information about the deprecation notice see our help center and for information about migrating to the Java SDK, see the Java Migration Guide.

Merge-SDK-Kotlin

The Kotlin/JVM SDK for accessing various Merge Unified APIs. We use the following dependencies:

  • Ktor for http communication
    • OkHttp engine (labeled Apache in ktor)
    • Jackson serialization engine
      • JSR 310 (java.time.OffsetDateTime for datetimes)
  • JUnit for tests
  • NO logging, aside from some println in tests

We target Java language level 8 and above. The API methods are written using Kotlin coroutines, but can be called with CompletableFutures see this example, as well as the unit test here. There should also be some packages that can make it work in Java 7, although we do not officially support it.

Build

You can find the latest published maven package here

The dependency in a maven pom will look something like:

<dependency>
  <groupId>dev.merge</groupId>
  <artifactId>client</artifactId>
  <version>2.0.9</version>
</dependency>

Usage

For all examples, you can refer to the BasicTest class in this repository.

Plain call, Kotlin

val accountsApi = AccountsApi()
accountsApi.setApiKey("REDACTED")
accountsApi.setAccountToken("REDACTED")

// or any other filters you prefer
val accountingAccountsResponse = accountsApi.accountsList(AccountsApi.AccountsListRequest(
    createdAfter=java.time.OffsetDateTime.now()
))

assertNotNull(accountingAccountsResponse)
assertNotNull(accountingAccountsResponse.results)

Plain call, Java

AccountsApi accountsApi = new AccountsApi();
accountsApi.setApiKey("REDACTED");
accountsApi.setAccountToken("REDACTED");

CompletableFuture<MergePaginatedResponse<Account>> accountingAccountsPromise = accountsApi.accountsListAsync(
    new AccountsApi.AccountsListRequest()
);

MergePaginatedResponse<Account> accountingAccountsResponse = accountingAccountsPromise.get();

assertNotNull(accountingAccountsResponse);
assertNotNull(accountingAccountsResponse.getResults());

Expands call, Kotlin

The expand parameter can be used during GET requests to fetch the related objects in your response body. For example, if you sent a request for GET /employees, you can use the expand parameter on Teams. This will fetch the associated Team data for each given employee. The Employee objects will be returned with the corresponding Teams objects instead of the default List<UUID>. In the below example, we expand the applications property of recruiting Candidate.

// debugging output
val mapper = ObjectMapper()
mapper.findAndRegisterModules()
mapper.enable(SerializationFeature.INDENT_OUTPUT)

// create api like normal
val candidatesApi = CandidatesApi()
candidatesApi.setApiKey("REDACTED")
candidatesApi.setAccountToken("REDACTED")

// note the "Expanded" suffix, returns a class of type Candidate.Expanded
val atsCandidatesExpandedResponse = candidatesApi.candidatesListExpanded(CandidatesApi.CandidatesListRequest(
  expand="applications"
))

// get candidates with expand=applications, check we have an expanded application sub object
assertNotNull(atsCandidatesExpandedResponse)
assertNotNull(atsCandidatesExpandedResponse.results)

for (candidate in atsCandidatesExpandedResponse.results ?: listOf()) {
    // since each candidate is now of type Candidate.Expanded, each property will be of type JsonNode or
    // List<JsonNode>, so in this case we take the first one and re-deserialize it again to type Application since we
    // had expanded it in our call. Other properties will remain the same.
    if (candidate.applications?.isNotEmpty() == true) {
        val applicationFromExpandedCandidate = mapper.convertValue(
            candidate.applications?.first(),
            Application::class.java
        )

        assertNotNull(applicationFromExpandedCandidate)
    }
  
    // of course, you may only want one property to be expanded and still have easy access to the other properties. To
    // get the non-expanded properties, use
    val candidateNormalized: Candidate = Candidate.Normalize(candidate)
    // this will convert all fields back to their strong types from JsonNode, if possible (it will even try to do so on
    // the expanded applications field which will error and gracefully continue to other properties)
    println(candidateNormalized.applications) // empty array
    println(candidateNormalized.id) // non-empty, non-JsonNode, uuid value
}

Remote Fields, Kotlin

Merge attempts to map as many enum values as possible from integrations into a single normalized set of enum values. However, there will always be edge cases where the default mapping does not suit our callers. In order to get the raw value, you can pass in the name of the enum parameter into the remoteFields request property:

val employeesApi = EmployeesApi()
employeesApi.setApiKey("REDACTED")
employeesApi.setAccountToken("REDACTED")

val hrisEmployeesResponse = employeesApi.employeesListExpanded(EmployeesApi.EmployeesListRequest(
  remoteFields="employment_status"
))

Using this feature looks very similar to the expands feature, in that you will be receiving raw JsonNode values and will need to deserialize to String yourself for the enum fields that are using the "remote field" functionality.

Resource cleanup

Each api client you create needs to allocate some resources. You should close the clients after use to dispose of those resources.

// using try / finally
AccountsApi accountsApi = null;

try {
  accountsApi = new AccountsApi();
  ...
} finally {
  if (accountsApi != null) {
    accountsApi.close()  
  }
}

// or using try-with-resources

try (AccountsApi accountsApi = new AccountsApi()) {
  ...
}
// using the `use` function
AccountsApi().use { 
    ...
}

About

The Kotlin/JVM SDK for accessing various Merge Unified APIs

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published