KissRequests AI Skill v0.1.0

This Markdown file is a versioned AI skill for using KissRequests in other Java projects. It is intentionally self-contained so an AI assistant can load this one document, add the Maven dependency, write consumer code, and avoid inventing APIs.

Use this skill for release 0.1.0. If the repository source is on a later -SNAPSHOT, consumer documentation should still use 0.1.0 unless the user explicitly asks for a snapshot build.

Library Summary

Tiny zero-dependency Java 17+ HTTP client facade over java.net.http.HttpClient with prepared calls, retries, file upload/download, streaming, multipart, and curl rendering.

Maven Dependency

<dependency>
  <groupId>io.github.arthurhoch</groupId>
  <artifactId>kiss-requests</artifactId>
  <version>0.1.0</version>
</dependency>

AI Usage Rules

Quick Example

Http http = Http.create();

HttpResult result = http.request(HttpMethod.GET, "https://example.com")
    .execute();

System.out.println(result.statusCode());
System.out.println(result.body());

How To Use The Library

Behavioral Contract For v0.1.0

Practical Examples

Reusable client with retries

Http http = Http.builder()
    .connectTimeout(Duration.ofSeconds(5))
    .requestTimeout(Duration.ofSeconds(20))
    .retryPolicy(RetryPolicy.of(3, Duration.ofMillis(250)))
    .maxConcurrentRequests(32)
    .build();

File download

Path target = Path.of("response.bin");
HttpDownloadResult download = http
    .download(HttpMethod.GET, "https://example.com/file", Map.of(), target)
    .execute();
System.out.println(download.bytesWritten());

Public API Specification

The following index is generated from compiled public classes with javap -public. It includes public constructors, constants, enum methods, record accessors, inherited Object overrides when public, and public nested classes.

When an internal package appears here, treat it as implementation detail unless the project documentation explicitly says otherwise. Consumer code should prefer the public surface described above.

public final class io.github.arthurhoch.kissrequests.Http {
  public static io.github.arthurhoch.kissrequests.Http create();
  public static io.github.arthurhoch.kissrequests.Http$Builder builder();
  public io.github.arthurhoch.kissrequests.HttpCall<io.github.arthurhoch.kissrequests.HttpResult> request(java.lang.String, java.lang.String);
  public io.github.arthurhoch.kissrequests.HttpCall<io.github.arthurhoch.kissrequests.HttpResult> request(java.lang.String, java.lang.String, java.util.Map<java.lang.String, java.lang.String>);
  public io.github.arthurhoch.kissrequests.HttpCall<io.github.arthurhoch.kissrequests.HttpResult> request(java.lang.String, java.lang.String, java.util.Map<java.lang.String, java.lang.String>, java.lang.String);
  public io.github.arthurhoch.kissrequests.HttpCall<io.github.arthurhoch.kissrequests.HttpResult> upload(java.lang.String, java.lang.String, java.util.Map<java.lang.String, java.lang.String>, java.nio.file.Path);
  public io.github.arthurhoch.kissrequests.HttpCall<io.github.arthurhoch.kissrequests.HttpDownloadResult> download(java.lang.String, java.lang.String, java.util.Map<java.lang.String, java.lang.String>, java.nio.file.Path);
  public io.github.arthurhoch.kissrequests.HttpCall<io.github.arthurhoch.kissrequests.HttpStreamResult> stream(java.lang.String, java.lang.String, java.util.Map<java.lang.String, java.lang.String>, java.lang.String);
  public io.github.arthurhoch.kissrequests.HttpCall<io.github.arthurhoch.kissrequests.HttpResult> multipart(java.lang.String, java.lang.String, java.util.Map<java.lang.String, java.lang.String>, java.util.Map<java.lang.String, java.lang.String>, java.util.Map<java.lang.String, java.nio.file.Path>);
}

public final class io.github.arthurhoch.kissrequests.Http$Builder {
  public io.github.arthurhoch.kissrequests.Http$Builder();
  public io.github.arthurhoch.kissrequests.Http$Builder connectTimeout(java.time.Duration);
  public io.github.arthurhoch.kissrequests.Http$Builder requestTimeout(java.time.Duration);
  public io.github.arthurhoch.kissrequests.Http$Builder retryPolicy(io.github.arthurhoch.kissrequests.RetryPolicy);
  public io.github.arthurhoch.kissrequests.Http$Builder maxConcurrentRequests(int);
  public io.github.arthurhoch.kissrequests.Http$Builder executor(java.util.concurrent.Executor);
  public io.github.arthurhoch.kissrequests.Http build();
}

public final class io.github.arthurhoch.kissrequests.HttpAttempt extends java.lang.Record {
  public io.github.arthurhoch.kissrequests.HttpAttempt(int, int, java.time.Duration, java.lang.String);
  public final java.lang.String toString();
  public final int hashCode();
  public final boolean equals(java.lang.Object);
  public int attemptNumber();
  public int statusCode();
  public java.time.Duration duration();
  public java.lang.String failureMessage();
}

public final class io.github.arthurhoch.kissrequests.HttpCall<T> {
  public T execute();
  public java.lang.String toCurl();
  public java.lang.String toCurlBase64();
  public java.lang.String method();
  public java.lang.String url();
  public java.util.Map<java.lang.String, java.lang.String> headers();
  public java.lang.String body();
  public java.nio.file.Path file();
  public java.nio.file.Path targetPath();
  public java.util.Map<java.lang.String, java.lang.String> fields();
  public java.util.Map<java.lang.String, java.nio.file.Path> fileFields();
  public io.github.arthurhoch.kissrequests.internal.CallType callType();
}

public final class io.github.arthurhoch.kissrequests.HttpConfig extends java.lang.Record {
  public io.github.arthurhoch.kissrequests.HttpConfig(java.time.Duration, java.time.Duration, io.github.arthurhoch.kissrequests.RetryPolicy, int, java.util.concurrent.Executor);
  public static io.github.arthurhoch.kissrequests.HttpConfig defaults();
  public final java.lang.String toString();
  public final int hashCode();
  public final boolean equals(java.lang.Object);
  public java.time.Duration connectTimeout();
  public java.time.Duration requestTimeout();
  public io.github.arthurhoch.kissrequests.RetryPolicy retryPolicy();
  public int maxConcurrentRequests();
  public java.util.concurrent.Executor executor();
}

public final class io.github.arthurhoch.kissrequests.HttpDownloadResult extends java.lang.Record {
  public io.github.arthurhoch.kissrequests.HttpDownloadResult(int, java.util.Map<java.lang.String, java.util.List<java.lang.String>>, java.nio.file.Path, long, java.time.Duration, java.util.List<io.github.arthurhoch.kissrequests.HttpAttempt>, java.lang.String, java.lang.String);
  public final java.lang.String toString();
  public final int hashCode();
  public final boolean equals(java.lang.Object);
  public int statusCode();
  public java.util.Map<java.lang.String, java.util.List<java.lang.String>> headers();
  public java.nio.file.Path file();
  public long bytesWritten();
  public java.time.Duration duration();
  public java.util.List<io.github.arthurhoch.kissrequests.HttpAttempt> attempts();
  public java.lang.String method();
  public java.lang.String url();
}

public class io.github.arthurhoch.kissrequests.HttpException extends java.lang.RuntimeException {
  public io.github.arthurhoch.kissrequests.HttpException(java.lang.String, java.lang.String, java.lang.String, java.util.List<io.github.arthurhoch.kissrequests.HttpAttempt>, java.time.Duration, int, java.util.Map<java.lang.String, java.util.List<java.lang.String>>, java.lang.String, java.lang.Throwable);
  public java.lang.String method();
  public java.lang.String url();
  public java.lang.String curl();
  public java.util.List<io.github.arthurhoch.kissrequests.HttpAttempt> attempts();
  public java.time.Duration totalDuration();
  public int statusCode();
  public java.util.Map<java.lang.String, java.util.List<java.lang.String>> responseHeaders();
  public java.lang.String responseBody();
  public synchronized java.lang.Throwable getCause();
  public java.lang.Throwable rootCause();
  public java.lang.String report();
  public static java.lang.String truncateBody(java.lang.String);
}

public final class io.github.arthurhoch.kissrequests.HttpMethod {
  public static final java.lang.String GET;
  public static final java.lang.String POST;
  public static final java.lang.String PUT;
  public static final java.lang.String DELETE;
  public static final java.lang.String PATCH;
  public static final java.lang.String HEAD;
  public static final java.lang.String OPTIONS;
}

public final class io.github.arthurhoch.kissrequests.HttpResult extends java.lang.Record {
  public io.github.arthurhoch.kissrequests.HttpResult(int, java.util.Map<java.lang.String, java.util.List<java.lang.String>>, java.lang.String, java.time.Duration, java.util.List<io.github.arthurhoch.kissrequests.HttpAttempt>, java.lang.String, java.lang.String);
  public final java.lang.String toString();
  public final int hashCode();
  public final boolean equals(java.lang.Object);
  public int statusCode();
  public java.util.Map<java.lang.String, java.util.List<java.lang.String>> headers();
  public java.lang.String body();
  public java.time.Duration duration();
  public java.util.List<io.github.arthurhoch.kissrequests.HttpAttempt> attempts();
  public java.lang.String method();
  public java.lang.String url();
}

public final class io.github.arthurhoch.kissrequests.HttpStreamResult extends java.lang.Record {
  public io.github.arthurhoch.kissrequests.HttpStreamResult(int, java.util.Map<java.lang.String, java.util.List<java.lang.String>>, java.io.InputStream, java.time.Duration, java.util.List<io.github.arthurhoch.kissrequests.HttpAttempt>, java.lang.String, java.lang.String);
  public final java.lang.String toString();
  public final int hashCode();
  public final boolean equals(java.lang.Object);
  public int statusCode();
  public java.util.Map<java.lang.String, java.util.List<java.lang.String>> headers();
  public java.io.InputStream inputStream();
  public java.time.Duration duration();
  public java.util.List<io.github.arthurhoch.kissrequests.HttpAttempt> attempts();
  public java.lang.String method();
  public java.lang.String url();
}

public final class io.github.arthurhoch.kissrequests.RetryPolicy {
  public static io.github.arthurhoch.kissrequests.RetryPolicy defaults();
  public static io.github.arthurhoch.kissrequests.RetryPolicy of(int);
  public static io.github.arthurhoch.kissrequests.RetryPolicy of(int, java.time.Duration);
  public static io.github.arthurhoch.kissrequests.RetryPolicy of(int, java.time.Duration, java.util.Set<java.lang.Integer>, java.util.Set<java.lang.String>);
  public int maxAttempts();
  public java.time.Duration initialBackoff();
  public java.util.Set<java.lang.Integer> retryOnStatusCodes();
  public java.util.Set<java.lang.String> retryOnMethods();
  public boolean shouldRetryOnStatus(int);
  public boolean shouldRetryMethod(java.lang.String);
}

public final class io.github.arthurhoch.kissrequests.internal.CallType extends java.lang.Enum<io.github.arthurhoch.kissrequests.internal.CallType> {
  public static final io.github.arthurhoch.kissrequests.internal.CallType TEXT;
  public static final io.github.arthurhoch.kissrequests.internal.CallType UPLOAD;
  public static final io.github.arthurhoch.kissrequests.internal.CallType DOWNLOAD;
  public static final io.github.arthurhoch.kissrequests.internal.CallType STREAM;
  public static final io.github.arthurhoch.kissrequests.internal.CallType MULTIPART;
  public static io.github.arthurhoch.kissrequests.internal.CallType[] values();
  public static io.github.arthurhoch.kissrequests.internal.CallType valueOf(java.lang.String);
}

public final class io.github.arthurhoch.kissrequests.internal.ConcurrencyLimiter {
  public io.github.arthurhoch.kissrequests.internal.ConcurrencyLimiter(int);
  public io.github.arthurhoch.kissrequests.internal.ConcurrencyLimiter$Token acquire() throws java.lang.InterruptedException;
}

public final class io.github.arthurhoch.kissrequests.internal.ConcurrencyLimiter$Token {
  public void release();
}

public final class io.github.arthurhoch.kissrequests.internal.CurlRenderer {
  public static java.lang.String render(io.github.arthurhoch.kissrequests.HttpCall<?>);
}

public final class io.github.arthurhoch.kissrequests.internal.HttpExecutionEngine {
  public io.github.arthurhoch.kissrequests.internal.HttpExecutionEngine(java.net.http.HttpClient, io.github.arthurhoch.kissrequests.HttpConfig);
  public java.lang.Object execute(io.github.arthurhoch.kissrequests.HttpCall<?>);
}

public final class io.github.arthurhoch.kissrequests.internal.MultipartBodyBuilder {
  public static java.lang.String generateBoundary();
  public static java.net.http.HttpRequest$BodyPublisher buildBody(java.util.Map<java.lang.String, java.lang.String>, java.util.Map<java.lang.String, java.nio.file.Path>, java.lang.String) throws java.io.IOException;
  public static long computeContentLength(java.util.Map<java.lang.String, java.lang.String>, java.util.Map<java.lang.String, java.nio.file.Path>, java.lang.String);
}

Local Verification Commands

Run these commands in the KissRequests repository when changing examples, docs, or release skill files:

mvn -B clean verify
mvn -B javadoc:javadoc

Release Skill Maintenance

For a future release such as 0.2.0, create a new file at docs/skills/v0.2.0.md instead of editing or deleting this historical file. Update docs/skills/index.md with a view link and a raw download link for the new version.