Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
The diff you're trying to view is too large. We only load the first 3000 changed files.
7 changes: 6 additions & 1 deletion .fernignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,9 @@ LICENSE.md
# Patch

src/main/java/com/merge/api/core/MergeApiApiError.java
src/main/java/com/merge/legacy
src/main/java/com/merge/legacy

# Fern is working on a fix to our code, which will automatically handle the logic we
# added to QueryStringMapper.java. Once that is fixed, we can remove this file from
# .fernignore.
src/main/java/com/merge/api/core/QueryStringMapper.java
6 changes: 3 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ jobs:

steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Set up Java
id: setup-jre
Expand All @@ -25,7 +25,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Set up Java
id: setup-jre
Expand All @@ -43,7 +43,7 @@ jobs:

steps:
- name: Checkout repo
uses: actions/checkout@v3
uses: actions/checkout@v4

- name: Set up Java
id: setup-jre
Expand Down
221 changes: 99 additions & 122 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Merge Java Library

[![Maven Central](https://img.shields.io/maven-central/v/dev.merge/merge-java-client)](https://central.sonatype.com/artifact/dev.merge/merge-java-client)
[![fern shield](https://img.shields.io/badge/%F0%9F%8C%BF-Built%20with%20Fern-brightgreen)](https://buildwithfern.com?utm_source=github&utm_medium=github&utm_campaign=readme&utm_source=https%3A%2F%2Fgithub.com%2Fmerge-api%2Fmerge-java-client)

The Merge Java SDK provides convenient access to the Merge API from Java or Kotlin.
The Merge Java library provides convenient access to the Merge API from Java.

## Documentation

Expand Down Expand Up @@ -68,169 +68,142 @@ Candidate candidate = mergeClient.ats().candidates().retrieve(

## Usage

Below are code snippets of how you can use the Java SDK.

### Create Link Token
Instantiate and use the client with the following:

```java
package com.example.usage;

import com.merge.api.MergeApiClient;
import com.merge.api.resources.ats.types.CategoriesEnum;
import com.merge.api.resources.ats.types.LinkToken;
import com.merge.api.resources.ats.linktoken.requests.EndUserDetailsRequest;
import com.merge.api.ats.types.ActivityEndpointRequest;
import com.merge.api.ats.types.ActivityRequest;

public class Example {
public static void main(String[] args) {
MergeApiClient client = MergeApiClient
.builder()
.apiKey("<token>")
.build();

client.ats().activities().create(
ActivityEndpointRequest
.builder()
.model(
ActivityRequest
.builder()
.build()
)
.remoteUserId("remote_user_id")
.build()
);
}
}
```

import java.util.List;
## Environments

MergeApiClient mergeClient = MergeApiClient.builder()
.accountToken("ACCOUNT_TOKEN")
.apiKey("API_KEY")
.build();
This SDK allows you to configure different environments for API requests.

LinkToken linkToken = mergeClient.ats().linkToken().create(EndUserDetailsRequest.builder()
.endUserEmailAddress("[email protected]")
.endUserOrganizationName("acme")
.endUserOriginId("1234")
.categories(List.of(CategoriesEnum.ATS))
.build());
```java
import com.merge.api.MergeApiClient;
import com.merge.api.core.Environment;

System.out.println("Created link token", linkToken.getLinkToken())
MergeApiClient client = MergeApiClient
.builder()
.environment(Environment.Production)
.build();
```

### Get Employee
## Base Url

You can set a custom base URL when constructing the client.

```java
import com.merge.api.MergeApiClient;
import com.merge.api.resources.hris.employees.requests.EmployeesRetrieveRequest;
import com.merge.api.resources.hris.types.Employee;

MergeApiClient mergeClient = MergeApiClient.builder()
.accountToken("ACCOUNT_TOKEN")
.apiKey("API_KEY")
MergeApiClient client = MergeApiClient
.builder()
.url("https://example.com")
.build();

Employee employee = mergeClient.hris().employees().retrieve(
"0958cbc6-6040-430a-848e-aafacbadf4ae",
EmployeesRetrieveRequest.builder()
.includeRemoteData(true)
.build());
```

### Get Candidate
## Exception Handling

```java
import com.merge.api.MergeApiClient;
import com.merge.api.resources.ats.types.Candidate;
import com.merge.api.resources.ats.candidates.requests.CandidatesRetrieveRequest;
When the API returns a non-success status code (4xx or 5xx response), an API exception will be thrown.

MergeApiClient mergeClient = MergeApiClient.builder()
.accountToken("ACCOUNT_TOKEN")
.apiKey("API_KEY")
.build();
```java
import com.merge.api.core.ApiError;

Candidate candidate = mergeClient.ats().candidates().retrieve(
"521b18c2-4d01-4297-b451-19858d07c133",
CandidatesRetrieveRequest.builder()
.includeRemoteData(true)
.build());
try {
client.ats().activities().create(...);
} catch (ApiError e) {
// Do something with the API exception...
}
```

### Filter Candidate
## Advanced

### Custom Client

This SDK is built to work with any instance of `OkHttpClient`. By default, if no client is provided, the SDK will construct one.
However, you can pass your own client like so:

```java
import com.merge.api.MergeApiClient;
import com.merge.api.resources.ats.candidates.requests.CandidatesListRequest;
import com.merge.api.resources.ats.types.PaginatedCandidateList;
import okhttp3.OkHttpClient;

import java.time.OffsetDateTime;
OkHttpClient customClient = ...;

MergeApiClient mergeClient = MergeApiClient.builder()
.accountToken("ACCOUNT_TOKEN")
.apiKey("API_KEY")
MergeApiClient client = MergeApiClient
.builder()
.httpClient(customClient)
.build();

PaginatedCandidateList candidate = mergeClient.ats().candidates().list(
CandidatesListRequest.builder()
.createdAfter(OffsetDateTime.parse("2007-12-03T10:15:30+01:00"))
.build());
```

### Get Contact
### Retries

```java
import com.merge.api.MergeApiClient;
import com.merge.api.resources.accounting.contacts.requests.ContactsRetrieveRequest;
import com.merge.api.resources.accounting.types.Contact;
The SDK is instrumented with automatic retries with exponential backoff. A request will be retried as long
as the request is deemed retryable and the number of retry attempts has not grown larger than the configured
retry limit (default: 2).

MergeApiClient mergeClient = MergeApiClient.builder()
.accountToken("ACCOUNT_TOKEN")
.apiKey("API_KEY")
.build();
A request is deemed retryable when any of the following HTTP status codes is returned:

Contact contact = mergeClient.accounting().contacts().retrieve(
"c640b80b-fac9-409f-aa19-1f9221aec445",
ContactsRetrieveRequest.builder()
.includeRemoteData(true)
.build());
```
- [408](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/408) (Timeout)
- [429](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/429) (Too Many Requests)
- [5XX](https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/500) (Internal Server Errors)

### Create Ticket
Use the `maxRetries` client option to configure this behavior.

```java
import com.merge.api.MergeApiClient;
import com.merge.api.resources.ticketing.tickets.requests.TicketEndpointRequest;
import com.merge.api.resources.ticketing.types.TicketRequest;
import com.merge.api.resources.ticketing.types.TicketRequestStatus;
import com.merge.api.resources.ticketing.types.TicketStatusEnum;
import java.time.OffsetDateTime;

MergeApiClient mergeClient = MergeApiClient.builder()
.accountToken("ACCOUNT_TOKEN")
.apiKey("API_KEY")
MergeApiClient client = MergeApiClient
.builder()
.maxRetries(1)
.build();

mergeClient.ticketing().tickets().create(TicketEndpointRequest.builder()
.model(TicketRequest.builder()
.name("Please add more integrations")
.creator("3fa85f64-5717-4562-b3fc-2c963f66afa6")
.dueDate(OffsetDateTime.parse("2022-10-11T00:00:00Z"))
.status(TicketRequestStatus.of(TicketStatusEnum.CLOSED))
.build())
.build());
```

### File Download
### Timeouts

The SDK defaults to a 60 second timeout. You can configure this with a timeout option at the client or request level.

```java
import com.merge.api.MergeApiClient;
import com.merge.api.resources.filestorage.types.PaginatedFileList;
import com.merge.api.resources.filestorage.files.requests.FilesListRequest;
import com.merge.api.resources.filestorage.types.File;

import java.io.InputStream;
import java.io.OutputStream;
import java.io.FileOutputStream;
import java.io.IOException;

MergeApiClient mergeClient = MergeApiClient.builder()
.accountToken("ACCOUNT_TOKEN")
.apiKey("API_KEY")
.build();
import com.merge.api.core.RequestOptions;

PaginatedFileList fileResponse = mergeClient.filestorage().files().list(FilesListRequest.builder()
.name("<FILE_NAME>")
.build());
// Client level
MergeApiClient client = MergeApiClient
.builder()
.timeout(10)
.build();

File file = fileResponse.getResults().get().get(0);
String fileId = file.getId().get();
InputStream fileContents = mergeClient.filestorage().files().downloadRetrieve(fileId);
byte[] buffer = new byte[1024]; // Set the buffer size to your desired value
try (OutputStream outputStream = new FileOutputStream("/path/to/file")) {
int bytesRead;
while ((bytesRead = fileContents.read(buffer)) != -1) {
outputStream.write(buffer, 0, bytesRead);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
// Request level
client.ats().activities().create(
...,
RequestOptions
.builder()
.timeout(10)
.build()
);
```

## Staged Builders
Expand All @@ -240,6 +213,10 @@ Staged builders only allow you to build the object once all required properties

## Contributing

While we value open-source contributions to this SDK, this library is generated programmatically. Additions made directly to this library would have to be moved over to our generation code, otherwise they would be overwritten upon the next generated release. Feel free to open a PR as a proof of concept, but know that we will not be able to merge it as-is. We suggest opening an issue first to discuss with us!
While we value open-source contributions to this SDK, this library is generated programmatically.
Additions made directly to this library would have to be moved over to our generation code,
otherwise they would be overwritten upon the next generated release. Feel free to open a PR as
a proof of concept, but know that we will not be able to merge it as-is. We suggest opening
an issue first to discuss with us!

On the other hand, contributions to the README are always very welcome!
On the other hand, contributions to the README are always very welcome!
4 changes: 2 additions & 2 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ java {

group = 'dev.merge'

version = '1.1.1'
version = '2.0.0'

jar {
dependsOn(":generatePomFileForMavenPublication")
Expand All @@ -71,7 +71,7 @@ publishing {
maven(MavenPublication) {
groupId = 'dev.merge'
artifactId = 'merge-java-client'
version = '1.1.1'
version = '2.0.0'
from components.java
pom {
licenses {
Expand Down
Binary file modified gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.14-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
Expand Down
6 changes: 3 additions & 3 deletions gradlew
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ case "$( uname )" in #(
NONSTOP* ) nonstop=true ;;
esac

CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
CLASSPATH="\\\"\\\""


# Determine the Java command to use to start the JVM.
Expand Down Expand Up @@ -205,15 +205,15 @@ fi
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'

# Collect all arguments for the java command:
# * DEFAULT_JVM_OPTS, JAVA_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# * DEFAULT_JVM_OPTS, JAVA_OPTS, and optsEnvironmentVar are not allowed to contain shell fragments,
# and any embedded shellness will be escaped.
# * For example: A user cannot expect ${Hostname} to be expanded, as it is an environment variable and will be
# treated as '${Hostname}' itself on the command line.

set -- \
"-Dorg.gradle.appname=$APP_BASE_NAME" \
-classpath "$CLASSPATH" \
org.gradle.wrapper.GradleWrapperMain \
-jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \
"$@"

# Stop when "xargs" is not available.
Expand Down
4 changes: 2 additions & 2 deletions gradlew.bat
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,11 @@ goto fail
:execute
@rem Setup the command line

set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
set CLASSPATH=


@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %*

:end
@rem End local scope for the variables with windows NT shell
Expand Down
2 changes: 1 addition & 1 deletion sample-app/src/main/java/sample/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@

public final class App {
public static void main(String[] args) {
// import com.merge.api.MergeApiClient
// import com.merge.api.AsyncMergeApiClient
}
}
Loading