CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/maven-io-ktor--ktor-client-js

Ktor HTTP client implementation for JavaScript platform providing asynchronous HTTP client functionality specifically tailored for JavaScript environments.

Pending
Overview
Eval results
Files

request-configuration.mddocs/

Request Configuration

Extensions for configuring individual HTTP requests with custom fetch options and JavaScript-specific parameters. This allows per-request customization beyond the engine-level configuration.

Capabilities

HttpRequestBuilder.fetchOptions Extension

Extension function that allows configuring individual HTTP requests with custom fetch options.

/**
 * Configures HTTP request with custom fetch options.
 * This allows setting request-specific fetch API options that override engine defaults.
 * 
 * @param block Configuration block for RequestInit options
 */
fun HttpRequestBuilder.fetchOptions(block: RequestInit.() -> Unit)

Usage Examples:

import io.ktor.client.*
import io.ktor.client.engine.js.*
import io.ktor.client.request.*

val client = HttpClient(Js)

// Configure specific request with custom fetch options
val response = client.get("https://api.example.com/data") {
    fetchOptions {
        credentials = "include"
        cache = "no-cache"
        mode = "cors"
    }
}

// POST request with custom options
val postResponse = client.post("https://api.example.com/submit") {
    fetchOptions {
        keepalive = true
        referrer = "no-referrer"
    }
    setBody("request data")
}

RequestInit Configuration Block

The configuration block provides access to all standard Fetch API RequestInit options for individual request customization.

/**
 * RequestInit interface for configuring fetch options
 * All properties are optional and override engine-level defaults
 */
interface RequestInit {
    /** HTTP method (GET, POST, etc.) - usually set by Ktor automatically */
    var method: String?
    
    /** Request headers - can supplement Ktor-managed headers */
    var headers: dynamic
    
    /** Request body - usually managed by Ktor */
    var body: dynamic
    
    /** Request mode: "cors", "no-cors", "same-origin", "navigate" */
    var mode: String?
    
    /** Credentials policy: "omit", "same-origin", "include" */
    var credentials: String?
    
    /** Cache control: "default", "no-store", "reload", "no-cache", "force-cache", "only-if-cached" */
    var cache: String?
    
    /** Redirect handling: "follow", "error", "manual" */
    var redirect: String?
    
    /** Referrer: URL string, "no-referrer", or "client" */
    var referrer: String?
    
    /** Referrer policy for privacy control */
    var referrerPolicy: String?
    
    /** Subresource integrity hash */
    var integrity: String?
    
    /** Keep connection alive for background requests */
    var keepalive: Boolean?
    
    /** AbortController signal for request cancellation */
    var signal: AbortSignal?
    
    /** Window object (browser environments only) */
    var window: dynamic
}

Common Request Configuration Patterns

Authentication Requests

import io.ktor.client.*
import io.ktor.client.engine.js.*
import io.ktor.client.request.*

val client = HttpClient(Js)

// Request with credentials for authentication
val userProfile = client.get("https://api.example.com/profile") {
    fetchOptions {
        credentials = "include" // Send cookies and auth headers
    }
}

// API request with no credentials
val publicData = client.get("https://api.example.com/public") {
    fetchOptions {
        credentials = "omit" // Don't send any credentials
    }
}

Cache Control Per Request

// Force fresh data from server
val freshData = client.get("https://api.example.com/live-data") {
    fetchOptions {
        cache = "no-cache" // Validate with server
    }
}

// Use cached data if available
val cachedData = client.get("https://api.example.com/static-data") {
    fetchOptions {
        cache = "force-cache" // Use cache if available
    }
}

// Never cache sensitive data
val sensitiveData = client.get("https://api.example.com/sensitive") {
    fetchOptions {
        cache = "no-store" // Never cache this response
    }
}

CORS Requests

// Cross-origin request with specific CORS settings
val corsResponse = client.post("https://external-api.com/endpoint") {
    fetchOptions {
        mode = "cors"
        credentials = "same-origin"
        referrerPolicy = "strict-origin-when-cross-origin"
    }
    setBody(jsonData)
}

// Same-origin only request
val sameOriginResponse = client.get("https://same-domain.com/api") {
    fetchOptions {
        mode = "same-origin" // Fail if cross-origin
    }
}

Background Requests

// Fire-and-forget background request
val analyticsResult = client.post("https://analytics.example.com/event") {
    fetchOptions {
        keepalive = true // Keep connection alive even if page unloads
    }
    setBody(analyticsData)
}

// Background sync with custom referrer
val syncResult = client.put("https://sync.example.com/data") {
    fetchOptions {
        keepalive = true
        referrer = "no-referrer" // Privacy protection
    }
    setBody(syncData)
}

Request Cancellation

import org.w3c.dom.AbortController

// Create abort controller for cancellation
val controller = AbortController()

// Request with cancellation support
val cancelableRequest = async {
    client.get("https://api.example.com/slow-endpoint") {
        fetchOptions {
            signal = controller.signal
        }
    }
}

// Cancel the request after 5 seconds
delay(5000)
controller.abort()

Security Headers

// Request with integrity checking
val secureResponse = client.get("https://cdn.example.com/library.js") {
    fetchOptions {
        integrity = "sha384-abc123def456..." // Expected hash
        referrer = "no-referrer" // Don't leak referrer
        cache = "default" // Allow caching of verified content
    }
}

// Privacy-focused request
val privateResponse = client.get("https://api.example.com/data") {
    fetchOptions {
        referrerPolicy = "no-referrer"
        mode = "cors"
        credentials = "omit" // No credentials for privacy
    }
}

Integration with Ktor Features

Combining with Request Builders

import io.ktor.client.request.*
import io.ktor.http.*

val response = client.post("https://api.example.com/upload") {
    // Standard Ktor configuration
    contentType(ContentType.Application.Json)
    setBody(requestData)
    timeout {
        requestTimeoutMillis = 30000
    }
    
    // JavaScript-specific fetch options
    fetchOptions {
        keepalive = true
        cache = "no-store"
        credentials = "include"
    }
}

With Custom Headers

val response = client.get("https://api.example.com/data") {
    // Ktor header management
    header("Authorization", "Bearer $token")
    header("Accept", "application/json")
    
    // Fetch-specific options
    fetchOptions {
        mode = "cors"
        credentials = "omit" // Don't send cookies despite Authorization header
        referrerPolicy = "strict-origin"
    }
}

Platform Considerations

  • Browser: All RequestInit options work as per Fetch API specification
  • Node.js: Some browser-specific options like window are ignored
  • WASM-JS: Limited support for advanced options depending on runtime capabilities

Error Handling

Configuration errors in fetchOptions are handled by the underlying Fetch API:

try {
    val response = client.get("https://api.example.com") {
        fetchOptions {
            mode = "same-origin" // Will fail for cross-origin requests
        }
    }
} catch (error: JsError) {
    // Handle fetch configuration errors
    println("Fetch error: ${error.origin}")
}

Install with Tessl CLI

npx tessl i tessl/maven-io-ktor--ktor-client-js

docs

engine-configuration.md

error-handling.md

fetch-api-types.md

http-engine.md

index.md

request-configuration.md

tile.json