Document Stack
Document Stack
Docs

Spring Boot Integration

Generate PDF documents from Spring Boot applications using the Document Stack REST API.

Setup

Spring Boot integrates with Document Stack via the REST API using RestClient (Spring 6.1+) or WebClient for reactive applications.

application.yml
documentstack:
  api-key: ${DS_API_KEY}
  base-url: https://api.documentstack.dev/api/v1

Configuration Class

DocumentStackConfig.java
@Configuration
@ConfigurationProperties(prefix = "documentstack")
public class DocumentStackConfig {
    private String apiKey;
    private String baseUrl;

    // getters and setters

    @Bean
    public RestClient documentStackClient() {
        return RestClient.builder()
            .baseUrl(baseUrl)
            .defaultHeader("Authorization", "Bearer " + apiKey)
            .defaultHeader("Content-Type", "application/json")
            .build();
    }
}

Service Class

DocumentStackService.java
@Service
public class DocumentStackService {

    private final RestClient client;

    public DocumentStackService(RestClient documentStackClient) {
        this.client = documentStackClient;
    }

    public GenerateResponse generate(String templateId, Map<String, Object> data) {
        var request = Map.of(
            "templateId", templateId,
            "data", data
        );

        return client.post()
            .uri("/generate")
            .body(request)
            .retrieve()
            .body(GenerateResponse.class);
    }

    public byte[] downloadPdf(String templateId, Map<String, Object> data) {
        var result = generate(templateId, data);
        return client.get()
            .uri(result.getData().getUrl())
            .retrieve()
            .body(byte[].class);
    }
}

Response DTOs

GenerateResponse.java
public record GenerateResponse(
    boolean success,
    GenerateData data
) {
    public record GenerateData(
        String url,
        String id
    ) {}
}

REST Controller

PdfController.java
@RestController
@RequestMapping("/api/pdf")
public class PdfController {

    private final DocumentStackService dsService;

    public PdfController(DocumentStackService dsService) {
        this.dsService = dsService;
    }

    @PostMapping("/generate")
    public ResponseEntity<?> generate(@RequestBody GenerateRequest request) {
        var result = dsService.generate(
            request.templateId(),
            request.data()
        );
        return ResponseEntity.ok(result);
    }

    @GetMapping("/download/{templateId}")
    public ResponseEntity<byte[]> download(@PathVariable String templateId) {
        byte[] pdf = dsService.downloadPdf(templateId, Map.of());

        return ResponseEntity.ok()
            .header("Content-Type", "application/pdf")
            .header("Content-Disposition",
                "attachment; filename=\"document.pdf\"")
            .body(pdf);
    }
}

record GenerateRequest(String templateId, Map<String, Object> data) {}

Error Handling

Exception Handler
@RestControllerAdvice
public class DocumentStackErrorHandler {

    @ExceptionHandler(RestClientResponseException.class)
    public ResponseEntity<?> handleDsError(RestClientResponseException ex) {
        return ResponseEntity
            .status(ex.getStatusCode())
            .body(Map.of(
                "success", false,
                "error", "PDF generation failed: " + ex.getMessage()
            ));
    }
}

Reactive Stack

For Spring WebFlux applications, replace RestClient with WebClient and return Mono/Flux types for non-blocking PDF generation.

Next Steps