🔧 Request Builder

KNET oferuje trzy sposoby budowania requestów: KNETRequest, Fluent Builder i Kotlin DSL.

1. KNETRequest - Data Class

Najprostszy sposób - bezpośrednie tworzenie obiektu request.

// Pełny konstruktor
val request = KNETRequest(
    url = "https://api.example.com/users",
    method = "POST",
    headers = mapOf(
        "Authorization" to "Bearer $token",
        "Content-Type" to "application/json"
    ),
    query = mutableMapOf(
        "include" to "profile"
    ),
    data = mapOf(
        "name" to "Jan Kowalski",
        "email" to "jan@example.com"
    ),
    timeout = 30_000,
    tag = "create-user"
)

val response = client.request(request)

Factory Methods

// GET
val request = KNETRequest.get("https://api.example.com/users")

// POST z danymi
val request = KNETRequest.post(
    "https://api.example.com/users",
    mapOf("name" to "Jan")
)

// PUT
val request = KNETRequest.put(
    "https://api.example.com/users/1",
    mapOf("name" to "Jan Nowak")
)

// DELETE
val request = KNETRequest.delete("https://api.example.com/users/1")

// PATCH
val request = KNETRequest.patch(
    "https://api.example.com/users/1",
    mapOf("email" to "nowy@example.com")
)

Modyfikacja z copy()

val baseRequest = KNETRequest.get("https://api.example.com/users")

// Dodaj nagłówki
val authRequest = baseRequest.copy(
    headers = baseRequest.headers + ("Authorization" to "Bearer $token")
)

// Zmień timeout
val slowRequest = baseRequest.copy(timeout = 60_000)

// Dodaj query
val pagedRequest = baseRequest.copy(
    query = mutableMapOf("page" to "2", "limit" to "20")
)

2. Fluent Builder

Chainowalne API dla czytelnego budowania requestów.

import rip.nerd.kitsunenet.builder.KNETFluentBuilder

val response = KNETFluentBuilder.post("https://api.example.com/users")
    .header("X-Custom", "value")
    .bearer("token123")
    .json(mapOf("name" to "Jan", "email" to "jan@example.com"))
    .timeout(30_000)
    .execute()

Dostępne metody

MetodaOpis
.header(name, value)Dodaje nagłówek
.headers(map)Dodaje wiele nagłówków
.bearer(token)Authorization: Bearer token
.basic(user, pass)Authorization: Basic base64
.contentType(type)Content-Type header
.accept(type)Accept header
.query(name, value)Dodaje query param
.queries(map)Dodaje wiele query params
.json(data)Body jako JSON
.form(data)Body jako form-urlencoded
.body(data)Raw body
.timeout(ms)Timeout w ms
.tag(tag)Tag requestu

Warunkowe budowanie

val response = KNETFluentBuilder.get(url)
    .applyIf(hasToken) { bearer(token) }
    .queryIf(page > 0, "page", page.toString())
    .headerIf(debugMode, "X-Debug", "true")
    .execute()

Multipart

val response = KNETFluentBuilder.post(uploadUrl)
    .bearer(token)
    .multipart {
        field("description", "Moje zdjęcie")
        field("tags", "vacation,summer")
        file("image", imageFile)
        file("thumbnail", thumbBytes, "thumb.jpg", "image/jpeg")
    }
    .execute()

3. Kotlin DSL

Najbardziej ekspresywny sposób z pełną mocą Kotlina.

import rip.nerd.kitsunenet.dsl.*

val response = knet {
    url = "https://api.example.com/users"
    method = POST

    headers {
        authorization("Bearer $token")
        contentType("application/json")
        accept("application/json")
        custom("X-Request-ID", UUID.randomUUID().toString())
    }

    query {
        param("include", "profile")
        param("fields", "id,name,email")
    }

    body {
        json(mapOf(
            "name" to "Jan Kowalski",
            "email" to "jan@example.com",
            "roles" to listOf("user", "admin")
        ))
    }

    timeout = 30_000
    tag = "create-user"
}

Różne typy body

// JSON z Map
body {
    json(mapOf("key" to "value"))
}

// JSON z obiektu
body {
    json(userObject)
}

// Form data
body {
    form(mapOf(
        "username" to "jan",
        "password" to "secret"
    ))
}

// Raw string
body {
    raw("plain text content")
}

// XML
body {
    xml("<user><name>Jan</name></user>")
}

Zaawansowane DSL

val response = knet {
    url = "https://api.example.com/upload"
    method = POST

    headers {
        bearer(authToken)
        custom("X-Idempotency-Key", idempotencyKey)
    }

    multipart {
        field("metadata", jsonMetadata)
        file("document", pdfFile)
        files("attachments", attachmentFiles)
    }

    // Callbacks
    onUploadProgress { sent, total ->
        updateProgress(sent * 100 / total)
    }

    retry {
        maxAttempts = 3
        exponentialBackoff = true
    }
}

Porównanie

Cecha KNETRequest Fluent Builder DSL
Prostota ⭐⭐⭐ ⭐⭐
Czytelność ⭐⭐ ⭐⭐⭐ ⭐⭐⭐
Elastyczność ⭐⭐ ⭐⭐⭐ ⭐⭐⭐
Warunki Ręcznie applyIf() Kotlin if/when

📚 Zobacz też