HTTP Methods Reference — Java 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 Java implementation — the same logic the interactive tool runs, in a shareable, citable form.
// Source: java.java
// Language: Java (Java 17, JDK standard library)
//
// 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.
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;
import java.util.Optional;
/**
* HTTP request-method reference — pure data + lookups.
*
* <p>The canonical {@link #METHODS} table holds the nine RFC 9110 / 9111
* methods with their semantic property flags. All helpers are read-only and
* hand out references into that single source of truth.</p>
*/
public final class HttpMethods {
/** One HTTP request method and its semantic properties. */
public record MethodEntry(
String method, // Uppercase method name, e.g. "GET".
boolean safe, // Read-only semantics — no server state change.
boolean idempotent, // Repeating the call has the same effect as a single call.
boolean cacheable, // Responses may be stored by a cache (RFC 9110 / MDN).
boolean hasBody, // The method conventionally carries a request body.
String description,
String typicalUse) {}
/** The nine HTTP request methods (RFC 9110 / 9111), in canonical order.
* An immutable {@link List#of} table — the single source of truth the
* helpers hand out references into. */
public static final List<MethodEntry> METHODS = List.of(
new MethodEntry("GET", true, true, true, false,
"Retrieves a representation of the target resource; a read-only request.",
"Fetching a web page, reading an API resource, loading an image."),
new MethodEntry("POST", false, false, true, true,
"Submits data to be processed, typically creating a new resource or triggering an action.",
"Submitting a form, creating a record, publishing a message."),
new MethodEntry("PUT", false, true, false, true,
"Replaces the target resource entirely with the request body.",
"Updating a full record at a known URL, uploading a file by its path."),
new MethodEntry("PATCH", false, false, false, true,
"Applies a partial modification to the target resource.",
"Updating one field of a record, toggling a flag."),
new MethodEntry("DELETE", false, true, false, false,
"Removes the target resource.",
"Deleting a record or file by its URL."),
new MethodEntry("HEAD", true, true, true, false,
"Identical to GET but returns only the response headers, no body.",
"Checking existence, size, or freshness before downloading."),
new MethodEntry("OPTIONS", true, true, false, false,
"Describes the communication options for the target resource.",
"CORS preflight requests, discovering allowed methods."),
new MethodEntry("CONNECT", false, false, false, false,
"Establishes a tunnel to the server (used with TLS/HTTPS proxies).",
"Proxying encrypted connections through an intermediary."),
new MethodEntry("TRACE", true, true, false, false,
"Performs a message loop-back test along the path to the target (debugging only).",
"Diagnosing request transformations by intermediaries."));
/** Narrowing options for {@link #filterMethods}.
* Each boolean is the boxed {@link Boolean} so callers can distinguish
* "constrain to {@code false}" from "no constraint" — a tri-state a bare
* {@code boolean} cannot express. {@code null} (the default) means no
* constraint. {@code query} is free text matched case-insensitively
* against method, description, and typicalUse; ignored when empty after
* trimming. */
public record MethodFilter(
Boolean safe,
Boolean idempotent,
Boolean cacheable,
String query) {
/** A filter with no constraints. */
public static MethodFilter none() {
return new MethodFilter(null, null, null, null);
}
}
/** Semantic diff between two methods. */
public record MethodComparison(
boolean sameSafety, // Both methods share the `safe` flag.
boolean sameIdempotence, // Both methods share the `idempotent` flag.
// One sentence per mismatched property (safe, idempotent, cacheable, hasBody).
List<String> differences) {}
private HttpMethods() {
// Static reference data — no instances.
}
/** Case-insensitive single-method lookup.
* Returns the entry, or empty when unknown — the Java analogue of TS's
* {@code MethodEntry | null}. ASCII method names: {@code toUpperCase}
* matches the TypeScript original for the alphabetic tokens. */
public static Optional<MethodEntry> getMethod(String name) {
String n = name.strip().toUpperCase(Locale.ROOT);
return METHODS.stream().filter(m -> m.method().equals(n)).findFirst();
}
/** Returns the methods satisfying every present flag and, when
* {@code query} is non-empty after trimming, matching it in at least one
* of {method, description, typicalUse}. */
public static List<MethodEntry> filterMethods(MethodFilter opts) {
MethodFilter o = opts != null ? opts : MethodFilter.none();
String q = o.query() == null ? "" : o.query().strip().toLowerCase(Locale.ROOT);
return METHODS.stream()
.filter(m -> flagMatches(o.safe(), m.safe())
&& flagMatches(o.idempotent(), m.idempotent())
&& flagMatches(o.cacheable(), m.cacheable())
&& (q.isEmpty() || matchesQuery(m, q)))
.toList();
}
/** Surfaces where two methods' semantics agree and differ.
* {@code differences} lists every mismatched property (safe, idempotent,
* cacheable, hasBody) as a human-readable sentence, reproducing the
* canonical phrasing verbatim so output stays identical to the
* TypeScript original and the other polyglot ports. */
public static MethodComparison compareMethods(MethodEntry a, MethodEntry b) {
List<String> differences = new ArrayList<>();
if (a.safe() != b.safe()) {
differences.add(a.method() + " is " + safeWord(a.safe())
+ ", " + b.method() + " is " + safeWord(b.safe()) + ".");
}
if (a.idempotent() != b.idempotent()) {
differences.add(a.method() + " is " + idempotentWord(a.idempotent())
+ ", " + b.method() + " is " + idempotentWord(b.idempotent()) + ".");
}
if (a.cacheable() != b.cacheable()) {
differences.add(a.method() + " is " + cacheableWord(a.cacheable())
+ ", " + b.method() + " is " + cacheableWord(b.cacheable()) + ".");
}
if (a.hasBody() != b.hasBody()) {
differences.add(a.method() + " " + bodyWord(a.hasBody())
+ ", " + b.method() + " " + bodyWord(b.hasBody()) + ".");
}
return new MethodComparison(a.safe() == b.safe(), a.idempotent() == b.idempotent(),
List.copyOf(differences));
}
/** Each present flag is an AND constraint; {@code null} means skip. */
private static boolean flagMatches(Boolean want, boolean actual) {
return want == null || actual == want;
}
private static boolean matchesQuery(MethodEntry m, String q) {
return m.method().toLowerCase(Locale.ROOT).contains(q)
|| m.description().toLowerCase(Locale.ROOT).contains(q)
|| m.typicalUse().toLowerCase(Locale.ROOT).contains(q);
}
// Phrasing helpers keep the difference-sentence wording in one place, so
// the output stays in lock-step across every polyglot port.
private static String safeWord(boolean v) {
return v ? "safe" : "not safe";
}
private static String idempotentWord(boolean v) {
return v ? "idempotent" : "not idempotent";
}
private static String cacheableWord(boolean v) {
return v ? "cacheable" : "not cacheable";
}
private static String bodyWord(boolean v) {
return v ? "takes a body" : "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 →