Advanced 18 min read

Wrapper and DTO Patterns for Apex Responses

By the end of this lesson, you'll be able to:

  • Explain why wrapper classes are used to shape Apex responses for LWC
  • Build an Apex wrapper class exposed via @AuraEnabled properties
  • Understand how Apex objects serialize to JSON for LWC

Prerequisites: "Calling Apex with @wire vs. Imperatively"

Why Wrap Data?

Returning raw sObjects directly works, but a wrapper class (often called a DTO — Data Transfer Object) is frequently the better choice: it decouples the component from the exact shape of the underlying object, avoids accidentally exposing fields the component doesn't need, and lets you combine data from multiple objects into one clean shape.

Building a Wrapper Class

public with sharing class AccountSummary {
    @AuraEnabled public Id accountId;
    @AuraEnabled public String accountName;
    @AuraEnabled public Integer openOpportunityCount;

    public AccountSummary(Id accountId, String accountName, Integer openOpportunityCount) {
        this.accountId = accountId;
        this.accountName = accountName;
        this.openOpportunityCount = openOpportunityCount;
    }
}

Each field that should be visible to LWC needs its own @AuraEnabled annotation — not just the class or method. This combines an Account's Name with a computed Opportunity count, something no single sObject query could return directly.

Serialization Rules

Apex-to-JSON serialization for @AuraEnabled properties is automatic — the property names are preserved exactly as declared in Apex when they arrive in JavaScript. There's no manual JSON-building step required, unlike calling a raw REST API from JavaScript.

Why This Matters in Real Projects

Returning a raw List<Account> directly ties the component to whatever fields happen to be queried; a wrapper class makes the contract between Apex and LWC explicit and stable, which matters a great deal as a project grows past a handful of components.

Exercise

Write an Apex wrapper class named ContactCard with @AuraEnabled fields for contactId (Id), fullName (String), and email (String).

Show hint

Each field needs its own @AuraEnabled annotation.

APEX

Exercise

Challenge: explain, as a comment, why annotating only the class (not each field) with @AuraEnabled would not work.

Show hint

Think about what @AuraEnabled actually controls exposure of.

APEX

Wrapper and DTO Patterns for Apex Responses Quiz

1. What is a wrapper (DTO) class used for in this context?

2. Does @AuraEnabled need to be applied to each individual property in a wrapper class?

3. What is one genuine benefit of using a wrapper class instead of returning a raw sObject?

4. How are Apex @AuraEnabled property names represented once serialized to JavaScript?

5. What must a wrapper class typically have to be constructed with initial values in Apex?

Log in to submit the quiz and save your score.

My Notes

Log in to keep private notes on this lesson.

Questions about this lesson

No questions yet — be the first to ask.

Log in to ask a question about this lesson.

Summary

A wrapper (DTO) class shapes an Apex response into exactly what a component needs — decoupling the UI from raw sObject shape and avoiding accidental overexposure of fields.