HTTP Methods Reference — Kotlin source
A searchable reference for every HTTP request method - GET, POST, PUT, PATCH, DELETE, and more. See at a glance which are safe, idempotent, and cacheable, then compare any two methods side by side.
This is the Kotlin implementation — the same logic the interactive tool runs, in a shareable, citable form.
// Source: kotlin.kt
// Language: Kotlin (Kotlin 1.9, standard library only)
//
// HTTP request-method reference — pure, deterministic data + lookups.
//
// CosmoDev polyglot showcase port of the `http-methods` tool, ported from
// src/lib/http-methods.ts. Functionally equivalent to the TypeScript original:
// identical inputs yield identical outputs (case-insensitive lookup, flag +
// free-text filtering, and a human-readable semantic comparison report).
//
// Property flags (safe / idempotent / cacheable / hasBody) follow RFC 9110
// and the MDN reference table.
//
// License: display source — part of CosmoDev's polyglot tool pages.
package cosmodev.httpmethods
/**
* One HTTP request method and its semantic properties.
*/
data class MethodEntry(
val method: String, // Uppercase method name, e.g. "GET".
val safe: Boolean, // Read-only semantics — no server state change.
val idempotent: Boolean, // Repeating the call has the same effect as a single call.
val cacheable: Boolean, // Responses may be stored by a cache (RFC 9110 / MDN).
val hasBody: Boolean, // The method conventionally carries a request body.
val description: String,
val typicalUse: String,
)
/**
* The nine HTTP request methods (RFC 9110 / 9111), in canonical order.
*
* An immutable [List] — the single source of truth the helpers hand out
* references into.
*/
val METHODS: List<MethodEntry> = listOf(
MethodEntry(
method = "GET",
safe = true,
idempotent = true,
cacheable = true,
hasBody = false,
description = "Retrieves a representation of the target resource; a read-only request.",
typicalUse = "Fetching a web page, reading an API resource, loading an image.",
),
MethodEntry(
method = "POST",
safe = false,
idempotent = false,
cacheable = true,
hasBody = true,
description = "Submits data to be processed, typically creating a new resource or triggering an action.",
typicalUse = "Submitting a form, creating a record, publishing a message.",
),
MethodEntry(
method = "PUT",
safe = false,
idempotent = true,
cacheable = false,
hasBody = true,
description = "Replaces the target resource entirely with the request body.",
typicalUse = "Updating a full record at a known URL, uploading a file by its path.",
),
MethodEntry(
method = "PATCH",
safe = false,
idempotent = false,
cacheable = false,
hasBody = true,
description = "Applies a partial modification to the target resource.",
typicalUse = "Updating one field of a record, toggling a flag.",
),
MethodEntry(
method = "DELETE",
safe = false,
idempotent = true,
cacheable = false,
hasBody = false,
description = "Removes the target resource.",
typicalUse = "Deleting a record or file by its URL.",
),
MethodEntry(
method = "HEAD",
safe = true,
idempotent = true,
cacheable = true,
hasBody = false,
description = "Identical to GET but returns only the response headers, no body.",
typicalUse = "Checking existence, size, or freshness before downloading.",
),
MethodEntry(
method = "OPTIONS",
safe = true,
idempotent = true,
cacheable = false,
hasBody = false,
description = "Describes the communication options for the target resource.",
typicalUse = "CORS preflight requests, discovering allowed methods.",
),
MethodEntry(
method = "CONNECT",
safe = false,
idempotent = false,
cacheable = false,
hasBody = false,
description = "Establishes a tunnel to the server (used with TLS/HTTPS proxies).",
typicalUse = "Proxying encrypted connections through an intermediary.",
),
MethodEntry(
method = "TRACE",
safe = true,
idempotent = true,
cacheable = false,
hasBody = false,
description = "Performs a message loop-back test along the path to the target (debugging only).",
typicalUse = "Diagnosing request transformations by intermediaries.",
),
)
/**
* Narrowing options for [filterMethods].
*
* Each boolean is `Boolean?` so callers can distinguish "constrain to
* `false`" from "no constraint" — a tri-state a bare [Boolean] cannot
* express. `null` (the default) means *no constraint*.
*/
data class MethodFilter(
val safe: Boolean? = null,
val idempotent: Boolean? = null,
val cacheable: Boolean? = null,
// Free text matched case-insensitively against method, description,
// and typicalUse. Ignored when empty after trimming.
val query: String? = null,
)
/**
* Semantic diff between two methods.
*/
data class MethodComparison(
val sameSafety: Boolean, // Both methods share the `safe` flag.
val sameIdempotence: Boolean, // Both methods share the `idempotent` flag.
// One sentence per mismatched property (safe, idempotent, cacheable, hasBody).
val differences: List<String>,
)
/**
* Case-insensitive single-method lookup.
*
* Returns the entry, or `null` when unknown — the Kotlin analogue of TS's
* `MethodEntry | null`.
*/
fun getMethod(name: String): MethodEntry? {
// ASCII method names: uppercase() is locale-invariant and matches the
// TypeScript original for the alphabetic tokens.
val n = name.trim().uppercase()
return METHODS.firstOrNull { it.method == n }
}
/**
* Filter the method set by boolean flags and an optional text query.
*
* A method must satisfy *every* present flag AND, when [MethodFilter.query]
* is non-empty after trimming, match it in at least one of
* {method, description, typicalUse}.
*/
fun filterMethods(opts: MethodFilter = MethodFilter()): List<MethodEntry> {
val q = opts.query?.trim()?.lowercase().orEmpty()
return METHODS.filter { m ->
// Each present flag is an AND constraint; null means skip.
(opts.safe == null || m.safe == opts.safe) &&
(opts.idempotent == null || m.idempotent == opts.idempotent) &&
(opts.cacheable == null || m.cacheable == opts.cacheable) &&
(
q.isEmpty() ||
m.method.lowercase().contains(q) ||
m.description.lowercase().contains(q) ||
m.typicalUse.lowercase().contains(q)
)
}
}
/**
* Compare two methods, surfacing where their semantics agree and differ.
*
* [MethodComparison.differences] lists every mismatched property (safe,
* idempotent, cacheable, hasBody) as a human-readable sentence, reproducing
* the canonical phrasing verbatim so output stays identical across ports.
*/
fun compareMethods(a: MethodEntry, b: MethodEntry): MethodComparison {
val differences = buildList {
if (a.safe != b.safe) {
add("${a.method} is ${safeWord(a.safe)}, ${b.method} is ${safeWord(b.safe)}.")
}
if (a.idempotent != b.idempotent) {
add("${a.method} is ${idempotentWord(a.idempotent)}, ${b.method} is ${idempotentWord(b.idempotent)}.")
}
if (a.cacheable != b.cacheable) {
add("${a.method} is ${cacheableWord(a.cacheable)}, ${b.method} is ${cacheableWord(b.cacheable)}.")
}
if (a.hasBody != b.hasBody) {
add("${a.method} ${bodyWord(a.hasBody)}, ${b.method} ${bodyWord(b.hasBody)}.")
}
}
return MethodComparison(
sameSafety = a.safe == b.safe,
sameIdempotence = a.idempotent == b.idempotent,
differences = differences,
)
}
// Phrasing helpers keep the difference-sentence wording in one place, so the
// output stays in lock-step across every polyglot port.
private fun safeWord(value: Boolean): String = if (value) "safe" else "not safe"
private fun idempotentWord(value: Boolean): String = if (value) "idempotent" else "not idempotent"
private fun cacheableWord(value: Boolean): String = if (value) "cacheable" else "not cacheable"
private fun bodyWord(value: Boolean): String = if (value) "takes a body" else "does not take a body"
Also available in 13 other languages
Every CosmoDev tool ships its pure logic in TypeScript (web) and Go (CLI), with authored implementations in a dozen-plus languages — the same contract, ported. Compare all languages side by side →