To understand how you should structure response data from the Apex controller, let's take an example of Apex code that is needed to display a list of accounts for a Lightning Component:
public class AccountController{ @AuraEnabled public Static List<AccountWrapper> queryAllAccounts(){ List<AccountWrapper> accountWrapperList = New List<AccountWrapper>(); List<Account> myAccounts = [Select id, Name, BillingState. (Select id From Contacts) From Account]; if(!myAccounts.isEmpty()){ for(Account currentAccount : myAccounts){ accountWrapperList.add(new AccountWrapper (..) ); } } return accountWrapperList; }}
This is the message/wrapper class code:
public class AccountWrapper{ @AuraEnabled