Skip to main content

Why Choose Juneau?

Apache Juneau™ combines a marshalling core with no required external dependencies, REST servers and clients that share one set of annotations, and in-process testing. Here's why developers choose Juneau over alternatives.

The Juneau Advantage​

One Dependency Story​

The juneau-marshall core needs only juneau-commons. A REST service adds the Jetty microservice bundle. Import the BOM once and leave versions off; see Install Juneau, and Framework Comparisons for how this compares.

Juneau:

<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.apache.juneau</groupId>
<artifactId>juneau-bom</artifactId>
<version>${juneau.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<dependencies>
<dependency>
<groupId>org.apache.juneau</groupId>
<artifactId>juneau-microservice-jetty-bundle</artifactId>
<type>pom</type>
</dependency>
</dependencies>

Alternative (Spring Boot + Jackson + Swagger):

<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
</dependency>
<dependency>
<groupId>org.springdoc</groupId>
<artifactId>springdoc-openapi-starter-webmvc-ui</artifactId>
</dependency>
<!-- Plus many more dependencies -->

Unified API, Multiple Formats​

Juneau provides a single, consistent API for serializing to multiple formats:

// One API, multiple formats
Person person = new Person("John", 30);

// JSON
String json = Json.of(person);

// XML
String xml = Xml.of(person);

// HTML
String html = Html.of(person);

// URL-Encoding
String urlEnc = UrlEncoding.of(person);

// ...and the rest of the 38 formats

With alternatives, you need different libraries and APIs for each format.

Self-Documenting REST APIs​

Juneau automatically generates Swagger documentation from your POJOs and annotations:

@Rest(title="User API", description="User management service")
public class UserResource extends BasicRestServlet {

@RestGet("/users/{id}")
public User getUser(@Path("id") String id) {
return userService.findById(id);
}

@RestPost("/users")
public User createUser(@Content User user) {
return userService.create(user);
}
}

Result: Swagger UI at /swagger with full API documentation, request/response schemas, and interactive testing. The Swagger v2 document is at /api and OpenAPI 3.1 at /openapi.

Type-Safe REST Client Proxies​

Create type-safe client interfaces that feel like local method calls:

// juneau-rest-client (org.apache.juneau.rest.client.RestClient)
@Remote("http://api.example.com")
public interface UserService {
@RemoteGet("/users/{id}")
User getUser(@Path("id") String id);

@RemotePost("/users")
User createUser(@Content User user);
}

// Use like a regular Java interface
UserService service = RestClient.builder().build().remote(UserService.class);
User user = service.getUser("123");

No more manual HTTP client code, JSON parsing, or error handling.

This uses juneau-rest-client, the recommended REST client. The Apache HttpClient-based juneau-rest-client-classic stays supported for existing users; see Choosing a REST Client.

Serverless Testing​

Test REST APIs without starting servers or containers:

@Test
public void testUserAPI() throws Exception {
try (MockRestClient mock = MockRestClient.create(UserResource.class);
var resp = mock.get("/users/123").run()) {
resp.assertThat().isOk().body().contains("John");
}
}

Fast, reliable tests with no server or network.

Token and Record Streaming​

Juneau 10 introduces a low-level streaming API for processing large datasets without buffering the entire document:

// Stream a large JSON5L (JSON5 Lines) file record-by-record — O(1) memory
try (RecordReader r = Json5l.DEFAULT.readRecords(inputStream)) {
while (r.canRead())
process(r.read(Person.class));
}

// Fine-grained structural token cursor (JSON, CBOR, MsgPack)
try (TokenReader r = Json.DEFAULT.readTokens(inputStream)) {
while (r.next() != TokenType.END_OF_STREAM) {
switch (r.getCurrentToken()) {
case FIELD_NAME -> System.out.print(r.getFieldName() + " = ");
case VALUE_STRING -> System.out.println(r.getString());
default -> { /* structural token, e.g. START_OBJECT/END_OBJECT */ }
}
}
}

RecordReader/RecordWriter work across every Juneau format; TokenReader/TokenWriter add fine-grained structural events for token-shaped formats (JSON family, CBOR, MsgPack). Both are first-class @RestOp parameter types, so REST endpoints can stream large responses directly to the client without intermediate buffering.

With alternatives, large-dataset streaming requires format-specific libraries and manual integration.

How Juneau Differs​

Each point links to the matching section of Framework Comparisons, which states the evidence.

  • Formats. 38 formats (26 in juneau-marshall, 12 RDF in juneau-marshall-rdf) through one API: JSON, XML, HTML, YAML, CSV, MessagePack, MarkdownDoc and more. juneau-marshall covers the core formats and juneau-marshall-rdf the RDF ones, where Jackson adds a jackson-dataformat-* module per format. See Juneau vs Jackson.
  • REST and API docs built in. Jackson is a data-binding library, not a REST framework. Spring Boot adds OpenAPI through an add-on such as SpringDoc, and JAX-RS through a separate library such as MicroProfile OpenAPI; Juneau generates it from @Rest and @RestOp. See Spring Boot and JAX-RS.
  • Content negotiation from one method. One Juneau method answers JSON, XML, HTML and the other registered formats based on Accept. Spring needs separate methods or HttpMessageConverter configuration per format; JAX-RS supports it through @Produces/@Consumes, with format-specific handling done by hand. See Spring Boot and JAX-RS.
  • Testing without a server. MockRestClient calls a resource in-process. Spring uses @SpringBootTest/@WebMvcTest or embedded containers; for JAX-RS it depends on the implementation and its test tooling. See Spring Boot.
  • Annotations, not a container. Juneau and Spring are both annotation-based. JAX-RS is a specification that needs an implementation such as Jersey or RESTEasy. Juneau resources can also run inside Spring Boot. See JAX-RS.

Real-World Benefits​

Enterprise Development​

  • Consistent APIs: Same patterns across serialization, REST services, and testing
  • Built-in Documentation: Automatic Swagger generation reduces documentation maintenance
  • Content Security Policy: First-class CSP header support with per-request nonce injection (10.0+), protecting the HTML UI and Swagger UI against XSS with a single opt-in setting

Microservices​

  • Flexible Deployment: Works with any Jakarta Servlet 6.1 container, embedded Jetty, or embedded Tomcat
  • Easy Testing: MockRestClient enables comprehensive testing without external services

API Development​

  • Rapid Prototyping: A running REST API in about 10 minutes: see Getting Started
  • Automatic Documentation: Swagger UI generated automatically from your code
  • Content Negotiation: Support multiple formats with no per-format setup
  • Type Safety: Compile-time checking for REST client interfaces
  • MCP Support: juneau-rest-server-mcp (revision-neutral core) plus the juneau-rest-server-mcp-v20260728 (current) and juneau-rest-server-mcp-v20250618 adapters expose any @Rest resource as a Model Context Protocol (MCP) endpoint, enabling LLM tool-calling with no additional framework — client-side MCP support (juneau-rest-client-mcp and its revision adapters) is also available

When to Choose Juneau​

This is guidance, not a measurement; for the feature-by-feature comparison see Framework Comparisons.

Perfect For:​

  • Multi-format APIs: When you need to support JSON, XML, HTML, and other formats
  • Rapid Development: When you want to build APIs quickly without complex configuration
  • Microservices: When you need lightweight services on embedded Jetty or Tomcat
  • Testing: When you want comprehensive testing without external dependencies
  • Documentation: When you need automatic API documentation generation
  • Learning: When you want to understand REST APIs without framework complexity

Consider Alternatives If:​

  • Heavy Spring Ecosystem: You're already deeply invested in Spring Boot's ecosystem
  • Complex Enterprise Features: You need advanced enterprise features like distributed transactions
  • Large Team: Your team has extensive experience with other frameworks
  • Legacy Integration: You need to integrate with existing Spring-based systems

Next​

Getting Started builds and runs a REST app in about 10 minutes.

Community and Support​

Conclusion​

Juneau offers an alternative to assembling several libraries. It provides a unified API for serialization, REST services, and testing, on a marshalling core with no required dependencies, so developers can focus on business logic rather than framework configuration.


Still not convinced? Check out our Framework Comparisons page for detailed technical comparisons, or explore our comprehensive examples to see Juneau in action.