Query parameter and form data handling with case-insensitive access, builder patterns, and comprehensive parameter manipulation utilities.
Case-insensitive parameter collection interface for query strings and form data.
/**
* Case-insensitive HTTP parameters collection (extends StringValues)
* Used for query parameters, form data, and other key-value collections
*/
interface Parameters : StringValues {
companion object {
/** Empty parameters instance */
val Empty: Parameters
/**
* Build parameters using DSL
* @param builder parameter builder function
* @return Parameters instance
*/
fun build(builder: ParametersBuilder.() -> Unit): Parameters
}
}Builder interface for constructing parameter collections.
/**
* Builder for constructing Parameters instances
*/
interface ParametersBuilder : StringValuesBuilder {
/**
* Build the final Parameters instance
* @return immutable Parameters collection
*/
fun build(): Parameters
}Convenient functions for creating Parameters instances from various inputs.
/**
* Create parameters builder with initial capacity
* @param size initial capacity hint
* @return ParametersBuilder instance
*/
fun ParametersBuilder(size: Int = 8): ParametersBuilder
/**
* Create empty parameters
* @return empty Parameters instance
*/
fun parametersOf(): Parameters
/**
* Create parameters with single name-value pair
* @param name parameter name
* @param value parameter value
* @return Parameters instance
*/
fun parametersOf(name: String, value: String): Parameters
/**
* Create parameters with single name and multiple values
* @param name parameter name
* @param values list of parameter values
* @return Parameters instance
*/
fun parametersOf(name: String, values: List<String>): Parameters
/**
* Create parameters from map of names to value lists
* @param map parameter map
* @return Parameters instance
*/
fun parametersOf(map: Map<String, List<String>>): Parameters
/**
* Create parameters from pairs of names to value lists
* @param pairs vararg pairs of parameter name to value list
* @return Parameters instance
*/
fun parametersOf(vararg pairs: Pair<String, List<String>>): Parameters
/**
* Create parameters using builder DSL
* @param builder parameter builder function
* @return Parameters instance
*/
fun parameters(builder: ParametersBuilder.() -> Unit): ParametersConcrete implementations of the Parameters interface for different use cases.
/**
* Builder implementation for constructing parameters
* @param size initial capacity hint
*/
class ParametersBuilderImpl(size: Int = 8) : ParametersBuilder
/**
* General parameters implementation backed by a map
* @param values map of parameter names to value lists
*/
class ParametersImpl(values: Map<String, List<String>>) : Parameters
/**
* Optimized single parameter implementation
* @param name parameter name
* @param values list of values for the parameter
*/
class ParametersSingleImpl(
name: String,
values: List<String>
) : ParametersOperator functions for combining parameter collections.
/**
* Combine two parameter collections
* @param other parameters to combine with
* @return new Parameters containing all parameters from both collections
*/
operator fun Parameters.plus(other: Parameters): ParametersUsage Examples:
import io.ktor.http.*
// Create empty parameters
val emptyParams = parametersOf()
// Create single parameter
val singleParam = parametersOf("key", "value")
// Create parameter with multiple values
val multiValueParam = parametersOf("tags", listOf("kotlin", "http", "api"))
// Create multiple parameters from pairs
val multipleParams = parametersOf(
"q" to listOf("search term"),
"limit" to listOf("10"),
"offset" to listOf("20"),
"sort" to listOf("name", "date")
)
// Create parameters using DSL builder
val builtParams = parameters {
append("category", "programming")
append("language", "kotlin")
append("tags", "multiplatform")
append("tags", "ios")
append("featured", "true")
}
// Access parameter values (case-insensitive)
val searchQuery = builtParams["q"] // Single value or null
val allTags = builtParams.getAll("tags") // List of all values or null
val limit = builtParams["limit"] // "10"
val sortOptions = builtParams.getAll("sort") // ["name", "date"]
// Check parameter existence
val hasCategory = builtParams.contains("category") // true
val hasFilter = "filter" in builtParams // false
// Iterate through parameters
builtParams.entries().forEach { (name, values) ->
println("$name: ${values.joinToString(", ")}")
}
// Case-insensitive access
val categoryLower = builtParams["category"] // Works
val categoryUpper = builtParams["CATEGORY"] // Also works (case-insensitive)
// Build parameters incrementally
val builder = ParametersBuilder()
builder.append("step", "1")
builder.append("action", "validate")
builder.appendAll("items", listOf("item1", "item2", "item3"))
// Build final parameters
val incrementalParams = builder.build()
// Combine parameter collections
val baseParams = parametersOf("version" to listOf("1.0"))
val additionalParams = parametersOf("debug" to listOf("true"))
val combinedParams = baseParams + additionalParams
// Work with form data parameters
val formParams = parameters {
append("username", "testuser")
append("password", "secret123")
append("remember", "true")
append("permissions", "read")
append("permissions", "write")
}
// Check all parameter names
val allNames = formParams.names()
println("Parameter names: $allNames")
// Check if parameters are empty
val isEmpty = formParams.isEmpty()
println("Is empty: $isEmpty")
// Create parameters from URL query string (conceptual - actual parsing done elsewhere)
val queryString = "q=kotlin&category=programming&tags=multiplatform&tags=ios"
// This would typically be parsed by URL parsing functions
// Advanced parameter manipulation
val searchParams = parameters {
append("q", "ktor http")
append("type", "library")
append("platform", "multiplatform")
append("language", "kotlin")
}
// Filter and transform parameters (using standard Kotlin collection operations on entries)
val filteredEntries = searchParams.entries().filter { (name, values) ->
name.startsWith("p") // Parameters starting with 'p'
}
// Create new parameters from filtered entries
val filteredParams = parametersOf(*filteredEntries.map { (name, values) ->
name to values
}.toTypedArray())
// Work with encoded parameter values (typically handled by URL utilities)
val encodedParams = parameters {
append("query", "special chars & symbols")
append("path", "/api/v1/search")
append("data", "key=value&other=data")
}
// Handle parameter arrays/lists
val arrayParams = parameters {
append("id", "1")
append("id", "2")
append("id", "3")
}
val allIds = arrayParams.getAll("id") // ["1", "2", "3"]
// Common parameter patterns
val paginationParams = parametersOf(
"page" to listOf("1"),
"size" to listOf("20"),
"sort" to listOf("created_date"),
"order" to listOf("desc")
)
val filterParams = parametersOf(
"status" to listOf("active", "pending"),
"category" to listOf("urgent"),
"assigned_to" to listOf("user123")
)
val apiParams = paginationParams + filterParams/**
* Base interface for string-based key-value collections
* (Inherited from Ktor's core utilities)
*/
interface StringValues {
/** Whether names are case-insensitive */
val caseInsensitiveName: Boolean
/** Get single value for name */
fun get(name: String): String?
/** Get all values for name */
fun getAll(name: String): List<String>?
/** Check if name exists */
fun contains(name: String): Boolean
/** Get all entries */
fun entries(): Set<Map.Entry<String, List<String>>>
/** Check if collection is empty */
fun isEmpty(): Boolean
/** Get all parameter names */
fun names(): Set<String>
}
/**
* Builder interface for StringValues
*/
interface StringValuesBuilder {
/** Append value to name */
fun append(name: String, value: String)
/** Append all values to name */
fun appendAll(name: String, values: Iterable<String>)
/** Remove all values for name */
fun remove(name: String)
/** Clear all parameters */
fun clear()
}