DEV Community

paohaijiao
paohaijiao

Posted on Originally published at paohaijiao.hashnode.dev

JQuickCurl vs OkHttp vs RestTemplate vs OpenFeign: A Honest Comparison for Backend Engineers

Choosing an HTTP client is a "boring but expensive" decision: it touches every downstream integration you own. OkHttp, Spring's RestTemplate, OpenFeign, and now curl-driven JQuickCurl all work — the real question is who should write and maintain your request definitions. This post compares the four on the dimensions that actually matter in a backend codebase, then gives you a decision framework.

The Contenders in One Line Each

Client Request definition style Best for
OkHttp Hand-written Request.Builder code Low-level control, streaming, custom protocols, performance-critical paths
RestTemplate Hand-written URIs + HttpEntity/HttpHeaders Classic Spring MVC codebases (deprecated in spirit by Spring in favor of WebClient)
OpenFeign Annotated Java interfaces (@GetMapping, etc.) Spring Cloud microservices with server-side (or declarative) contracts
JQuickCurl Raw curl strings parsed by ANTLR4, plus variables & XML Teams that live in Postman/browser curl and want zero hand-written request construction

What the Code Looks Like Side by Side

OkHttp — everything explicit, everything manual:

HttpUrl url = HttpUrl.get("https://jsonplaceholder.typicode.com/posts")
        .newBuilder()
        .addQueryParameter("userId", "1")
        .build();

RequestBody body = RequestBody.create(
        "{\"title\":\"ok\",\"body\":\"bar\",\"userId\":1}",
        MediaType.get("application/json; charset=utf-8"));

Request request = new Request.Builder()
        .url(url)
        .addHeader("Accept", "application/json")
        .post(body)
        .build();

try (Response response = new OkHttpClient().newCall(request).execute()) {
    System.out.println(response.body() != null ? response.body().string() : "");
}
Enter fullscreen mode Exit fullscreen mode

RestTemplate — annotations gone, strings everywhere:

RestTemplate rest = new RestTemplate();
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> entity = new HttpEntity<>("{\"title\":\"ok\",\"userId\":1}", headers);

ResponseEntity<Map> resp = rest.exchange(
        "https://jsonplaceholder.typicode.com/posts?userId={id}",
        HttpMethod.POST, entity, Map.class, 1);
System.out.println(resp.getBody());
Enter fullscreen mode Exit fullscreen mode

OpenFeign — contract-driven, but only if the contract exists:

@FeignClient(name = "posts", url = "https://jsonplaceholder.typicode.com")
public interface PostClient {
    @PostMapping(value = "/posts", consumes = "application/json")
    Map<String, Object> create(@RequestBody Map<String, Object> payload);
}
Enter fullscreen mode Exit fullscreen mode

JQuickCurl — the tested curl snippet is the code:

public interface PostApi {
    @JCurlCommand("curl -X POST https://jsonplaceholder.typicode.com/posts "
            + "-H 'Content-Type: application/json' "
            + "-d '{\"title\":\"ok\",\"body\":\"bar\",\"userId\":1}'")
    String create(JQuickCurlReq request);
}
Enter fullscreen mode Exit fullscreen mode

The differences become obvious: OkHttp/RestTemplate force you to re-describe the request in builder API; OpenFeign introduces a parallel annotation vocabulary; JQuickCurl reuses the universal curl vocabulary you already test with.

Comparison Table: What Actually Differs

Criterion OkHttp RestTemplate OpenFeign JQuickCurl
Reuse Postman/browser curl Manual rewrite Manual rewrite Manual rewrite Paste directly
Dynamic requests (headers/body per call) Code branches Code branches SpEL / interceptors Variables ${...} + XML <if>
Cross-team sharing of request format None None Contract stubs Same curl string
Proxy / dynamic invocation N/A N/A Yes Yes (createProxy)
Timeouts/retry/pool out of the box Builder Some Via config Global JQuickCurlConfig
Multipart upload / download Manual Manual Manual -F / --output in curl
Spring Cloud integration No Native template Native Bean wiring (manual, simple)
Dependency weight Small Spring Web Spring Cloud stack OkHttp + ANTLR runtime
Learning curve for new devs Medium Low Low–Medium Low if they know curl

When to Pick JQuickCurl (Honest Scenarios)

Choose JQuickCurl when:

  • You or your QA team already maintain curl collections in Postman and want them as executable Java code.
  • Third-party OpenAPI docs ship curl samples and you must integrate many endpoints quickly (see Post 18).
  • You need dynamic requests that depend on runtime state (auth tokens, environment hosts, feature flags) without writing factory methods per endpoint.
  • You want API definitions externalized in XML, decoupled from business code.

Still choose the alternatives when:

  • You are deep inside the Spring Cloud ecosystem and already own Feign clients — the load-balancer/service-discovery integration is a solved problem there.
  • You need WebFlux/reactive non-blocking I/O — JQuickCurl's model is synchronous OkHttp calls (though OkHttp itself is async-capable under the hood).
  • You only have a handful of endpoints and the team knows one client cold — introducing any new abstraction has a cost.

Decision Checklist

  1. Do your requests already exist as curl commands? → strong signal for JQuickCurl.
  2. Do you run a microservice mesh with Feign today? → stay on Feign unless curl reuse is a bigger pain.
  3. Do you need reactive streaming? → OkHttp/WebClient territory.
  4. Do you want one tool for the whole team to read requests? → JQuickCurl wins on readability.

Summary

None of these tools is universally "best". OkHttp is the raw engine, RestTemplate the legacy workhorse, OpenFeign the Spring-Cloud native, and JQuickCurl the only one that treats curl as a first-class, shareable request language. JQuickCurl is not a replacement for a full service-discovery stack — it's an alternative to hand-writing request builders, and in curl-heavy, integration-heavy codebases it removes a surprising amount of boilerplate. Source: dromara/jquick-curl.

In Post 4 we'll do something every backend dev needs: reuse curl snippets exported straight from Postman and the browser, without translating them by hand.

java #springboot #httpclient #opensource #java-library

Top comments (0)