diff --git a/unirest-bdd-tests/src/test/java/BehaviorTests/CachingTest.java b/unirest-bdd-tests/src/test/java/BehaviorTests/CachingTest.java index 7d60bbbe..43462978 100644 --- a/unirest-bdd-tests/src/test/java/BehaviorTests/CachingTest.java +++ b/unirest-bdd-tests/src/test/java/BehaviorTests/CachingTest.java @@ -61,6 +61,17 @@ void canCacheResponsesForEqualRequests() { assertEquals(r1, r2); } + @Test + void queryAlsoCaches() { + Unirest.config().cacheResponses(true); + + var r1 = Unirest.get(MockServer.QUERY).asObject(RequestCapture.class).getBody().requestId; + var r2 = Unirest.get(MockServer.QUERY).asObject(RequestCapture.class).getBody().requestId; + + assertEquals(1, MockServer.timesCalled); + assertEquals(r1, r2); + } + @Test void canCacheResponsesForEqualRequests_async() throws Exception { Unirest.config().cacheResponses(true); diff --git a/unirest-bdd-tests/src/test/java/BehaviorTests/MockServer.java b/unirest-bdd-tests/src/test/java/BehaviorTests/MockServer.java index e9b28cda..696d2594 100644 --- a/unirest-bdd-tests/src/test/java/BehaviorTests/MockServer.java +++ b/unirest-bdd-tests/src/test/java/BehaviorTests/MockServer.java @@ -76,6 +76,7 @@ public class MockServer { public static final String POST = HOST + "/post"; public static final String GET = HOST + "/get"; public static final String ERROR_RESPONSE = HOST + "/error"; + public static final String QUERY = HOST + "/query"; public static final String DELETE = HOST + "/delete"; public static final String GZIP = HOST + "/gzip"; public static final String EMPTY_GZIP = HOST + "/empty-gzip"; @@ -129,6 +130,7 @@ public static void reset() { c.routes.get("/sparkle/{spark}/yippy", MockServer::sparkle); c.routes.post("/post", MockServer::jsonResponse); c.routes.get("/get", MockServer::jsonResponse); + c.routes.query("/query", MockServer::jsonResponse); c.routes.get("/gzip", MockServer::gzipResponse); c.routes.post("/empty-gzip", MockServer::emptyGzipResponse); c.routes.get("/redirect", MockServer::redirect); diff --git a/unirest-bdd-tests/src/test/java/BehaviorTests/QueryMethodTest.java b/unirest-bdd-tests/src/test/java/BehaviorTests/QueryMethodTest.java new file mode 100644 index 00000000..9f7dce53 --- /dev/null +++ b/unirest-bdd-tests/src/test/java/BehaviorTests/QueryMethodTest.java @@ -0,0 +1,53 @@ +/** + * The MIT License + * + * Copyright for portions of unirest-java are held by Kong Inc (c) 2013. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject to + * the following conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE + * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION + * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + */ + +package BehaviorTests; + +import kong.unirest.core.Unirest; +import org.junit.jupiter.api.Test; + +public class QueryMethodTest extends BddTest { + @Test + void canUseQueryVerbWithFormFields() { + Unirest.query(MockServer.QUERY) + .queryString("foo", "bar") + .field("fruit", "apple") + .asObject(RequestCapture.class) + .getBody() + .assertParam("foo", "bar") + .assertParam("fruit", "apple"); + } + + @Test + void canUseQueryVerbWithUniBody() { + Unirest.query(MockServer.QUERY) + .queryString("foo", "bar") + .body("this is a very complicated query") + .asObject(RequestCapture.class) + .getBody() + .assertParam("foo", "bar") + .assertBody("this is a very complicated query"); + } +} diff --git a/unirest/src/main/java/kong/unirest/core/HttpMethod.java b/unirest/src/main/java/kong/unirest/core/HttpMethod.java index 4e789c3f..95ef13c3 100644 --- a/unirest/src/main/java/kong/unirest/core/HttpMethod.java +++ b/unirest/src/main/java/kong/unirest/core/HttpMethod.java @@ -30,17 +30,36 @@ import java.util.Map; import java.util.Set; +/** + * Represents an HTTP method (verb) such as GET, POST, or PUT. + *

+ * Unlike a fixed enum, instances are interned in an internal registry, so custom + * or non-standard verbs can be created and reused via {@link #valueOf(String)}. + * Standard verbs are provided as constants for convenience. + *

+ */ public class HttpMethod { private static final Map REGISTRY = new HashMap<>(); + /** The HTTP GET method. */ public static final HttpMethod GET = valueOf("GET"); + /** The HTTP POST method. */ public static final HttpMethod POST = valueOf("POST"); + /** The HTTP QUERY method. */ + public static final HttpMethod QUERY = valueOf("QUERY"); + /** The HTTP PUT method. */ public static final HttpMethod PUT = valueOf("PUT"); + /** The HTTP DELETE method. */ public static final HttpMethod DELETE = valueOf("DELETE"); + /** The HTTP PATCH method. */ public static final HttpMethod PATCH = valueOf("PATCH"); + /** The HTTP HEAD method. */ public static final HttpMethod HEAD = valueOf("HEAD"); + /** The HTTP OPTIONS method. */ public static final HttpMethod OPTIONS = valueOf("OPTIONS"); + /** The HTTP TRACE method. */ public static final HttpMethod TRACE = valueOf("TRACE"); + /** The pseudo-method used for WebSocket connections. */ public static final HttpMethod WEBSOCKET = valueOf("WEBSOCKET"); private final String name; @@ -49,14 +68,28 @@ private HttpMethod(String name){ this.name = name; } + /** + * Return the interned {@link HttpMethod} for the given verb, creating it if necessary. + * The verb is normalized to upper case, so lookups are case-insensitive. + * @param verb the HTTP method name + * @return the corresponding HttpMethod instance + */ public static HttpMethod valueOf(String verb){ return REGISTRY.computeIfAbsent(String.valueOf(verb).toUpperCase(), HttpMethod::new); } + /** + * Return all HttpMethod instances currently registered. + * @return a set of all known HttpMethods + */ public Set all(){ return new HashSet<>(REGISTRY.values()); } + /** + * Return the name of this HTTP method. + * @return the method name in upper case + */ public String name() { return name; } diff --git a/unirest/src/main/java/kong/unirest/core/Unirest.java b/unirest/src/main/java/kong/unirest/core/Unirest.java index 5ca595ad..0e825288 100644 --- a/unirest/src/main/java/kong/unirest/core/Unirest.java +++ b/unirest/src/main/java/kong/unirest/core/Unirest.java @@ -25,6 +25,23 @@ package kong.unirest.core; +/** + * Static entry point for the primary Unirest client. + *

+ * Use this facade to access the default shared {@link UnirestInstance}, configure + * the global client, create requests, or spawn isolated instances when you need + * separate configuration. + *

+ * + *

Typical usage

+ *
{@code
+ * Unirest.config().defaultBaseUrl("https://api.example.com");
+ * String body = Unirest.get("/status").asString().getBody();
+ * }
+ * + * @see UnirestInstance + * @see Config + */ public class Unirest { private static UnirestInstance primaryInstance = new UnirestInstance(new Config()); @@ -116,6 +133,15 @@ public static HttpRequestWithBody put(String url) { return primaryInstance.put(url); } + /** + * Start a QUERY HttpRequest from the primary config. + * @param url the endpoint to access. Can include placeholders for path params using curly braces {} + * @return A HttpRequest builder + */ + public static HttpRequestWithBody query(String url){ + return primaryInstance.query(url); + } + /** * Start a PATCH HttpRequest which supports a JSON Patch builder. * this supports RFC-6902 https://tools.ietf.org/html/rfc6902 @@ -126,14 +152,30 @@ public static JsonPatchRequest jsonPatch(String url) { return primaryInstance.jsonPatch(url); } + /** + * Start an HttpRequest for the given HTTP method from the primary config. + * @param method the HTTP method name + * @param url the endpoint to access. Can include placeholders for path params using curly braces {} + * @return A HttpRequest builder + */ public static HttpRequestWithBody request(String method, String url) { return primaryInstance.request(method, url); } + /** + * Start a WebSocket request from the primary config. + * @param url the endpoint to access + * @return a WebSocket request builder + */ public static WebSocketRequest webSocket(String url) { return primaryInstance.webSocket(url); } + /** + * Start a Server-Sent Events request from the primary config. + * @param url the endpoint to access + * @return an SSE request builder + */ public static SseRequest sse(String url) { return primaryInstance.sse(url); } @@ -150,9 +192,8 @@ public static UnirestInstance spawnInstance() { } /** - * return the primary UnirestInstance. - * - * @return a new UnirestInstance + * Return the shared primary {@link UnirestInstance}. + * @return the primary instance */ public static UnirestInstance primaryInstance() { return primaryInstance; diff --git a/unirest/src/main/java/kong/unirest/core/UnirestInstance.java b/unirest/src/main/java/kong/unirest/core/UnirestInstance.java index e635a56d..3a17696b 100644 --- a/unirest/src/main/java/kong/unirest/core/UnirestInstance.java +++ b/unirest/src/main/java/kong/unirest/core/UnirestInstance.java @@ -102,6 +102,15 @@ public HttpRequestWithBody post(String url) { return new HttpRequestBody(config, HttpMethod.POST, url); } + /** + * Start a QUERY HttpRequest from this instance. + * @param url the endpoint to access. Can include placeholders for path params using curly braces {} + * @return a HttpRequest builder + */ + public HttpRequestWithBody query(String url) { + return new HttpRequestBody(config, HttpMethod.QUERY, url); + } + /** * Start a DELETE HttpRequest which supports a body from the primary config * @param url the endpoint to access. Can include placeholders for path params using curly braces {} @@ -139,6 +148,12 @@ public JsonPatchRequest jsonPatch(String url) { return new HttpRequestJsonPatch(config, url); } + /** + * Start an HttpRequest for the given HTTP method. + * @param method the HTTP method name + * @param url the endpoint to access. Can include placeholders for path params using curly braces {} + * @return a HttpRequest builder + */ public HttpRequestWithBody request(String method, String url) { return new HttpRequestBody(config, HttpMethod.valueOf(method), url); } @@ -153,10 +168,20 @@ public void close() { reset(true); } + /** + * Start a WebSocket request from this instance. + * @param url the endpoint to access + * @return a WebSocket request builder + */ public WebSocketRequest webSocket(String url) { return new WebSocketRequestImpl(config, url); } + /** + * Start a Server-Sent Events request from this instance. + * @param url the endpoint to access + * @return an SSE request builder + */ public SseRequestImpl sse(String url) { return new SseRequestImpl(config, url); }