RequestBuilder.java
package com.guinetik.rr.request;
import com.guinetik.rr.http.RocketHeaders;
import java.util.HashMap;
import java.util.Map;
/**
* Fluent builder for constructing {@link RequestSpec} instances.
*
* <p>This builder provides a clean, type-safe API for creating HTTP request specifications
* with all necessary parameters like endpoint, method, headers, body, and response type.
*
* <h2>Static Factory Methods</h2>
* <pre class="language-java"><code>
* // GET request
* RequestSpec<Void, User> getUser = RequestBuilder.<Void, User>get("/users/1")
* .responseType(User.class)
* .build();
*
* // POST request with body
* RequestSpec<CreateUser, User> createUser = RequestBuilder.<CreateUser, User>post("/users")
* .body(new CreateUser("John", "john@example.com"))
* .responseType(User.class)
* .build();
*
* // PUT request
* RequestSpec<UpdateUser, User> updateUser = RequestBuilder.<UpdateUser, User>put("/users/1")
* .body(new UpdateUser("John Doe"))
* .responseType(User.class)
* .build();
*
* // DELETE request
* RequestSpec<Void, Void> deleteUser = RequestBuilder.<Void, Void>delete("/users/1")
* .responseType(Void.class)
* .build();
* </code></pre>
*
* <h2>With Headers and Query Params</h2>
* <pre class="language-java"><code>
* Map<String, String> params = new HashMap<>();
* params.put("page", "1");
* params.put("limit", "10");
*
* RequestSpec<Void, UserList> request = RequestBuilder.<Void, UserList>get("/users")
* .queryParams(params)
* .headers(RocketHeaders.defaultJson().set("X-Custom", "value"))
* .responseType(UserList.class)
* .build();
* </code></pre>
*
* @param <Req> the type of the request body
* @param <Res> the type of the response
* @author guinetik <guinetik@gmail.com>
* @see RequestSpec
* @since 1.0.0
*/
public class RequestBuilder<Req, Res> {
private String endpoint;
private String method = "GET";
private Map<String, String> queryParams = new HashMap<>();
private RocketHeaders headers = RocketHeaders.defaultJson();
private Req body;
private Class<Res> responseType;
/**
* Creates a GET request builder for the specified endpoint.
*
* @param endpoint the API endpoint.
* @param <Req> The type of the request body.
* @param <Res> The type of the response.
* @return a new builder instance.
*/
public static <Req, Res> RequestBuilder<Req, Res> get(String endpoint) {
return new RequestBuilder<Req, Res>().endpoint(endpoint).method("GET");
}
/**
* Creates a POST request builder for the specified endpoint.
*
* @param endpoint the API endpoint.
* @param <Req> The type of the request body.
* @param <Res> The type of the response.
* @return a new builder instance.
*/
public static <Req, Res> RequestBuilder<Req, Res> post(String endpoint) {
return new RequestBuilder<Req, Res>().endpoint(endpoint).method("POST");
}
/**
* Creates a PUT request builder for the specified endpoint.
*
* @param endpoint the API endpoint.
* @param <Req> The type of the request body.
* @param <Res> The type of the response.
* @return a new builder instance.
*/
public static <Req, Res> RequestBuilder<Req, Res> put(String endpoint) {
return new RequestBuilder<Req, Res>().endpoint(endpoint).method("PUT");
}
/**
* Creates a DELETE request builder for the specified endpoint.
*
* @param endpoint the API endpoint.
* @param <Req> The type of the request body.
* @param <Res> The type of the response.
* @return a new builder instance.
*/
public static <Req, Res> RequestBuilder<Req, Res> delete(String endpoint) {
return new RequestBuilder<Req, Res>().endpoint(endpoint).method("DELETE");
}
/**
* Sets the API endpoint for the request.
*
* @param endpoint the API endpoint.
* @return the builder instance.
*/
public RequestBuilder<Req, Res> endpoint(String endpoint) {
this.endpoint = endpoint;
return this;
}
/**
* Sets the HTTP method for the request.
*
* @param method the HTTP method (e.g., GET, POST, PUT, DELETE).
* @return the builder instance.
*/
public RequestBuilder<Req, Res> method(String method) {
this.method = method;
return this;
}
/**
* Sets the query parameters for the request.
*
* @param queryParams a map of query parameters.
* @return the builder instance.
*/
public RequestBuilder<Req, Res> queryParams(Map<String, String> queryParams) {
this.queryParams = queryParams;
return this;
}
/**
* Adds a single query parameter to the request.
*
* @param name the parameter name.
* @param value the parameter value.
* @return the builder instance.
*/
public RequestBuilder<Req, Res> queryParam(String name, String value) {
this.queryParams.put(name, value);
return this;
}
/**
* Sets the headers for the request.
*
* @param headers a map of headers.
* @return the builder instance.
*/
public RequestBuilder<Req, Res> headers(RocketHeaders headers) {
this.headers = headers;
return this;
}
/**
* Sets the body of the request.
*
* @param body the request body.
* @return the builder instance.
*/
public RequestBuilder<Req, Res> body(Req body) {
this.body = body;
return this;
}
/**
* Sets the expected response type of the request.
*
* @param responseType the response type.
* @return the builder instance.
*/
public RequestBuilder<Req, Res> responseType(Class<Res> responseType) {
this.responseType = responseType;
return this;
}
/**
* Builds and returns a {@link RequestSpec} instance.
*
* @return the constructed {@link RequestSpec}.
*/
public RequestSpec<Req, Res> build() {
return new RequestSpec<>(endpoint, method, queryParams, headers, body, responseType);
}
}