function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Pablo Ledesma 8Pablo Ledesma 8 

Create an Apex REST service that returns an account and it's contacts.

Hi
I have been trying to pass this challenge (https://trailhead.salesforce.com/en/trails/force_com_dev_intermediate/modules/apex_integration_services/units/apex_integration_webservices):

To pass this challenge, create an Apex REST class that is accessible at '/Accounts/<Account_ID>/contacts'. The service will return the account's ID and Name plus the ID and Name of all contacts associated with the account. Write unit tests that achieve 100% code coverage for the class and run your Apex tests.
The Apex class must be called 'AccountManager'.
The Apex class must have a method called 'getAccount' that is annotated with @HttpGet
The method must return the ID and Name for the requested record and all associated contacts with their ID and Name.
The unit tests must be in a separate Apex class called 'AccountManagerTest'.
The unit tests must cover all lines of code included in the AccountManager class, resulting in 100% code coverage.
Run your test class at least once (via 'Run All' tests the Developer Console) before attempting to verify this challenge.

I getting this error:

Challenge Not yet complete... here's what's wrong: 
Executing the 'AccountManager' method failed. Either the service isn't configured with the correct urlMapping, is not global, does not have the proper method name or does not return the requested account and all of its contacts.

This is my code:
 
@RestResource(urlMapping='/Accounts/*/contacts')
global with sharing class AccountManager {
	
    @HttpGet
    global static List<sObject> getAccount(){
        RestRequest request = RestContext.request;
        List<String> urlParams = request.requestURI.split('/');
        
        String accountId;	
        for(String param: urlParams){
            if((param != 'Accounts') && (param != 'contacts'))
                accountId = param;
        }
    
        List<Account> lstAccounts = new List<Account>();
        lstAccounts = [SELECT Id, Name FROM Account WHERE Id = :accountId];
        
        List<sObject> result = new List<sObject>();
        result.add(lstAccounts[0]);
        
        List<Contact> lstContacts = [SELECT Id, Name FROM Contact WHERE AccountId = :accountId];
        for(Contact c:lstContacts){
            result.add(c);
        }
        return result;
    }
}

This is my response
 
[ {
  "attributes" : {
    "type" : "Account",
    "url" : "/services/data/v39.0/sobjects/Account/001o0000015hgVBAAY"
  },
  "Id" : "001o0000015hgVBAAY",
  "Name" : "SFDC Computing"
}, {
  "attributes" : {
    "type" : "Contact",
    "url" : "/services/data/v39.0/sobjects/Contact/003o000001DbYc8AAF"
  },
  "Id" : "003o000001DbYc8AAF",
  "Name" : "Pepito Peres"
}, {
  "attributes" : {
    "type" : "Contact",
    "url" : "/services/data/v39.0/sobjects/Contact/003o000001BsUPwAAN"
  },
  "Id" : "003o000001BsUPwAAN",
  "Name" : "Last0"
} ]

Can someone light my way?​
Best Answer chosen by Pablo Ledesma 8
Sandeep WaliaSandeep Walia
Hi Pablo,

The requirement for the challenge is to return Account and its related contacts, which can be achieved using one SOQL query. I am sharing the code for my apex class that successfully passed the challenge.
//Apex Class

@RestResource(urlMapping='/Accounts/*/contacts')
global with sharing class AccountManager{
    @HttpGet
    global static Account getAccount(){
        RestRequest request = RestContext.request;
        String accountId = request.requestURI.substringBetween('Accounts/','/contacts');
        system.debug(accountId);
        Account objAccount = [SELECT Id,Name,(SELECT Id,Name FROM Contacts) FROM Account WHERE Id = :accountId LIMIT 1];
        return objAccount;
    }
}


//Test  class
@isTest 
private class AccountManagerTest{
    static testMethod void testMethod1(){
        Account objAccount = new Account(Name = 'test Account');
        insert objAccount;
        Contact objContact = new Contact(LastName = 'test Contact',
                                         AccountId = objAccount.Id);
        insert objContact;
        Id recordId = objAccount.Id;
        RestRequest request = new RestRequest();
        request.requestUri =
            'https://sandeepidentity-dev-ed.my.salesforce.com/services/apexrest/Accounts/'
            + recordId +'/contacts';
        request.httpMethod = 'GET';
        RestContext.request = request;
        // Call the method to test
        Account thisAccount = AccountManager.getAccount();
        // Verify results
        System.assert(thisAccount!= null);
        System.assertEquals('test Account', thisAccount.Name);
    }
}

While your code did provide the evrything that was required the JSON returned in the case of single SOQL  is different as compared to your JSON.

Hope this helps,
Sandeep 

All Answers

Sandeep WaliaSandeep Walia
Hi Pablo,

The requirement for the challenge is to return Account and its related contacts, which can be achieved using one SOQL query. I am sharing the code for my apex class that successfully passed the challenge.
//Apex Class

@RestResource(urlMapping='/Accounts/*/contacts')
global with sharing class AccountManager{
    @HttpGet
    global static Account getAccount(){
        RestRequest request = RestContext.request;
        String accountId = request.requestURI.substringBetween('Accounts/','/contacts');
        system.debug(accountId);
        Account objAccount = [SELECT Id,Name,(SELECT Id,Name FROM Contacts) FROM Account WHERE Id = :accountId LIMIT 1];
        return objAccount;
    }
}


//Test  class
@isTest 
private class AccountManagerTest{
    static testMethod void testMethod1(){
        Account objAccount = new Account(Name = 'test Account');
        insert objAccount;
        Contact objContact = new Contact(LastName = 'test Contact',
                                         AccountId = objAccount.Id);
        insert objContact;
        Id recordId = objAccount.Id;
        RestRequest request = new RestRequest();
        request.requestUri =
            'https://sandeepidentity-dev-ed.my.salesforce.com/services/apexrest/Accounts/'
            + recordId +'/contacts';
        request.httpMethod = 'GET';
        RestContext.request = request;
        // Call the method to test
        Account thisAccount = AccountManager.getAccount();
        // Verify results
        System.assert(thisAccount!= null);
        System.assertEquals('test Account', thisAccount.Name);
    }
}

While your code did provide the evrything that was required the JSON returned in the case of single SOQL  is different as compared to your JSON.

Hope this helps,
Sandeep 
This was selected as the best answer
Prashant MaxsteelPrashant Maxsteel
@RestResource(urlMapping='/Accounts/*/contacts')
global with sharing class AccountManager {

    @HttpGet
    global static cust_AcnCon1 getAccount() {
        //Option1 - 2 queries and minimal processing
        RestRequest request = RestContext.request;
        String sID          = request.requestURI.substringBetween('Accounts/','/contacts');
        cust_AcnCon1 sObj1  = new cust_AcnCon1();
        Map<Id,Account> sM1 = new Map<Id,Account>([Select Id, Name from Account where Id= :sID ]);
        
        String sString1 = 'Incorrect Id';
        If (sM1.size() == 0){
        	System.Debug('No Records Retrieved for the Id:'+ sID);
        }
        else if (sM1.Size() > 1){
        	System.Debug('Multiple Records Retrieved for the Id:'+sId);            
        }
        else if (sM1.size() == 1){
        	System.Debug('Account Id:'+ sID);            
        }
        //why Map? Just for fun
        sObj1.AccountId   = sM1.get(sID).Id;
        sObj1.AccountName = sM1.get(sID).Name;
        sObj1.ChildCon    = new List<Contact>([Select Id, Name from Contact where AccountId = :sID]);
        sObj1.sTest1      = True;
        return sObj1;
        
        //can think of an
        //	Aggregate Result
        //	Object - need to check
        //	List/Array
    } 
    
    global class cust_AcnCon1{
            
		Global String AccountId=null;
        Global String AccountName=null;
        Global List<Contact> ChildCon=null;
        Global Boolean sTest1 = False;
    }
}

Test Class:
@isTest
private class AccountManagerTest {

    @isTest 
    static void testClassObject(){
        AccountManager.cust_AcnCon1 sObj1 = new  AccountManager.cust_AcnCon1();
		System.AssertEquals(null,sObj1.AccountId);
		System.AssertEquals(null,sObj1.AccountName); 
		System.AssertEquals(null,sObj1.ChildCon);         
        System.AssertEquals(False,sObj1.sTest1);

    }   
    
    @isTest 
    static void testGetCaseById() {
        Id sId = createTestRecord(2);

        RestRequest request = new RestRequest();
        request.requestUri = 'https://eu11.salesforce.com/services/apexrest/Accounts/'+sId+'/contacts';
        request.httpMethod = 'GET';
        RestContext.request = request;

        // Call the method to test

        AccountManager.cust_AcnCon1 sObj2 = new  AccountManager.cust_AcnCon1();
        sObj2 = AccountManager.getAccount();

        // Verify results
        System.assert(sObj2 != null);
        System.assertEquals(sId, sObj2.AccountId);
        System.assertEquals('Test Record 1.1',sObj2.AccountName);
        System.assertEquals(2,sObj2.ChildCon.size());
    }
    
    static public ID createTestRecord(Integer sCount){
        
        ID sId;
        Account sAc1 = new Account(Name = 'Test Record 1.1');
        Insert sAc1;
        sId = sAc1.Id;
        
        List <Contact> sCon = new List<Contact>();
        For (Integer i = 0; i<sCount; i++){
            sCon.add(new Contact(FirstName = 'Test'+i, LastName = 'Freud', AccountId = sId));
            	System.Debug('Test - Contact['+i+'] record add.');
        }
        Insert sCon;
        
        return sId;
    }
}

So, instead of passing Account, I have passed a custom Class; however the Challenge mentions it is incorrect
Challenge Not yet complete... here's what's wrong: 
Executing the 'AccountManager' method failed. Either the service isn't configured with the correct urlMapping, is not global, does not have the proper method name or does not return the requested account and all of its contacts.

I have checked the output, which seemed fine for me.
Could you tell me, what is wrong with my approach?

Workbench output
Arun Kumar TharanichelvanArun Kumar Tharanichelvan
Hi,
I'm running into same issue, couldn't clear the challenge with the below code. Is there anything that I'm missing. Thanks in advance for your help!

Apex class -
@RestResource(urlMapping='/Accounts/*/contacts')
global class AccountManager {

    @HttpGet
    global static Account getAcccount() {
        RestRequest request = RestContext.request;
        // grab the AccountId from the end of the URL
        String accountId =  request.requestURI.substringBetween('Accounts/', '/contacts');
        System.debug(accountId);
        Account result =  [SELECT id,name,(Select id,name from Contacts)from Account
                        WHERE Id = :accountId LIMIT 1];
        return result;
    }
}

Test Class -
@isTest
private class AccountManagerTest {
    @isTest static void testGetAccountById() {
        Id recordId = createTestRecord();
        // Set up a test request
        RestRequest request = new RestRequest();
        request.requestUri =
            'https://actionfire-dev-ed.my.salesforce.com/services/apexrest/Accounts/'
            + recordId +'/contacts';
        request.httpMethod = 'GET';
        RestContext.request = request;
        // Call the method to test
        Account thisAcc = AccountManager.getAcccount();
    
    }

    // Helper method
    static Id createTestRecord() {
        // Create test record
       Account testAcc = new Account(name='Test Account123');
        insert testAcc;
        
        Contact Cont1 = new Contact();
        Cont1.LastName = 'ABC';
        Cont1.AccountId = testAcc.Id ;
        insert Cont1;

        Contact Cont2 = new Contact();
        Cont2.LastName = 'XYZ';
        Cont2.AccountId =testAcc.Id ;
        insert Cont2 ;
      
        return testAcc.Id;
    }          

}
Prashant MaxsteelPrashant Maxsteel
Hi @Arun,
  1. What's the error encountered on Challenge check?
  2. Does the Test have 100% coverage?
  3. What does the Workbench result show?
Additionally, instead of using 2 insert operations onto DB, can't you use a List and insert at the end?
Arun Kumar TharanichelvanArun Kumar Tharanichelvan
Here's the error at the end of challenge -
Challenge Not yet complete... here's what's wrong: 
Executing the 'AccountManager' method failed. Either the service isn't configured with the correct urlMapping, is not global, does not have the proper method name or does not return the requested account and all of its contacts.


Yes the Test coverage is 100%
Workbench result - 
{ "attributes" : { "type" : "Account", "url" : "/services/data/v40.0/sobjects/Account/001610000091HIRAA2" }, "Id" : "001610000091HIRAA2", "Name" : "University of Arizona", "Contacts" : { "totalSize" : 2, "done" : true, "records" : [ { "attributes" : { "type" : "Contact", "url" : "/services/data/v40.0/sobjects/Contact/00361000006nS5jAAE" }, "AccountId" : "001610000091HIRAA2", "Id" : "00361000006nS5jAAE", "Name" : "Jane Grey" }, { "attributes" : { "type" : "Contact", "url" : "/services/data/v40.0/sobjects/Contact/0036100001G0WtkAAF" }, "AccountId" : "001610000091HIRAA2", "Id" : "0036100001G0WtkAAF", "Name" : "ffff" } ] } }
Raghav ThadepRaghav Thadep
Here is the error I am facing while checking the challenge.
There was an unexpected error in your org which is preventing this assessment check from completing: System.QueryException: Aggregate query has too many rows for direct assignment, use FOR loop

Can anyone help me find this error was occuring.

@RestResource(urlMapping = '/Accounts/*/contacts')
global with sharing class AccountManager 
{
@HttpGet
    global static Account getAccount()
    {
      RestRequest request = RestContext.request;
      String accId = request.requestURI.substringBetween('Accounts/','/contacts');
      system.debug(accId);
      Account acct = [SELECT Id,Name,(SELECT Id,Name FROM Contacts) FROM Account WHERE Id = :accId LIMIT 1];
      return acct;  
    } 
}

@isTest
private class AccountManagerTest 
{
    static testMethod void testMethod1()
    {
        Account accTst = new Account(Name = 'Test Account');
        insert accTst;
        Contact conTst = new Contact(LastName = 'Test Contact', AccountId = accTst.Id);
        insert conTst;
        ID recId = accTst.Id;
        RestRequest request = new RestRequest();
        request.requestUri = 'https://login.salesforce.com/services/apexrest/Accounts/'+recId+'/contacts';
        request.httpMethod = 'GET';
        RestContext.request = request;
        Account thisAcc = AccountManager.getAccount();
        system.debug(thisAcc);
        system.assert(thisAcc != null);
        system.assertEquals('Test Account', thisAcc.Name);
    }
}
rita sharm 4rita sharm 4
I have a question. Account object has no Contact object in its Model class and even not able to fetch contact list from Account object. Then How the question id ok? Kindly clarify.
Hugo FurthHugo Furth
My opinion....Sandeep's solution meets the letter of the challenge. Prashant's code is more likely what one would implement in the real world.

I think the challenge is fundamentally flawed.....it asks you to return an Account object but also specifies that it wants the contact info. However, the list of contact objects are not part of the Account object.

Sandeep's code returns the correct data and has a valid test for Account. But you cannot test the contact information unless you use a custom object (as Prashant has) but then, as noted, you cannot pass the challenge. 
CarljohnsonCarljohnson
It is an amazing article and proves knowledgeable information and I am read this blog and I really like this blog thank you to shares with us. If you have interest in games then visit this amazing website for cheats and commands - gtacheatcode and click here for GTA cheats ps4.
Govind siyagGovind siyag
vjhv
Govind siyagGovind siyag
Attitude status |सबसे अच्छे ऐटीट्यूड स्टेटस हिन्दी |Attitude status in hindi 

more shayari  https://love-life.in/attitude-status/

शेर अपनी ताकत से raja कहलाता है ,
क्योकि जगल में चुनाव नही होते .
Govind siyagGovind siyag
शेर अपनी ताकत से raja कहलाता है ,
क्योकि जगल में चुनाव नही होते .

more https://love-life.in/attitude-status/

Attitude status |सबसे अच्छे ऐटीट्यूड स्टेटस हिन्दी |Attitude status in hindi
Alizey ShahAlizey Shah
Agreed With Sandeep Solution. (https://fabulaes.com/)
Shayari Ka PitaraShayari Ka Pitara
Are you looking for the best shayari website https://shayarikapitara.com/? Then there is only one shayari platform that will actually deliver the various types of shayaris like love shayari, cute shayari, romantic shayari, sad shayari, sorry shayari etc. i.e. Shayari Ka Pitara
Rahul Kumar DeyRahul Kumar Dey
Hi,

You can also try below codes to pass the challenge.

AccountManager.apxc
@RestResource(urlMapping='/Accounts/*/contacts')
Global with sharing class AccountManager {
    @HttpGet
    global static Account getAccount(){
        RestRequest request = RestContext.request;
        //Grab the accountId from end of URL
        String accountId = request.requestURI.substringBetween('Accounts/','/contacts');
        Account acc = [select Id,Name,(select Id,Name from Contacts) from Account where Id = :accountId];
        system.debug('Account and Related Contacts->>>>'+acc);
        return acc;
    }
}

AccountManagerTest.apxc
@isTest
private class AccountManagerTest {
    //Helper method to create dummy record
    static Id createTestRecord(){
        //Create test record
        Account TestAcc = new Account(Name='Test Account', Phone='8786757657');
        insert TestAcc;
        List<Contact> conList = new List<Contact>();
        Contact TestCon = new Contact();
        for(Integer i=1;i<=3;i++){
            TestCon.LastName = 'Test Contact'+i;
            TestCon.AccountId = TestAcc.Id;
            //conList.add(TestCon);
            insert conList;//Its not best practice but I have use it for testing purposes
        }
        //insert conList;
        //insert TestAcc;
        return TestAcc.Id;
    } 
    
    //Method to test getAccount()
    @isTest static void getAccountTest(){
        Id recordId = createTestRecord();
        //setup a test request
        RestRequest request = new RestRequest();
        //set request properties
        request.requestURI = 'https://yourInstance.salesforce.com/services/apexrest/Accounts/' + recordId +'/contacts';
        request.httpMethod = 'GET';
        // Finally, assign the request to RestContext if used
        RestContext.request = request;
        //End test setup
        
        //Call the method
        Account thisAcc = AccountManager.getAccount();
        //Verify the result
        system.assert(thisAcc != null);
        system.assertEquals('Test Account', thisAcc.Name);
        //system.assertEquals(3, thisAcc.Contact__c.size()); how to get this
    }
}

Now go to workbench and give your accountId and test it out.

Here I got below response-

User-added image
 
Ronilo Jr. AlvaradoRonilo Jr. Alvarado
@RestResource(urlMapping='/Accounts/*/Contacts')

global with sharing class AccountManager {

    @HttpGet
    global static Account getAccount(){
        RestRequest request = RestContext.request;
        
        String accId = request.requestURI.substringBetween('/Accounts/*/Contacts');
        
        Account result = [Select Id, Name,(Select Id, Name FROM Contacts)
                          From Account Where Id =: AccId];
        return result;
        
    }
    
    
    
}
-----------------------------------------------
@isTest
private class AccountManagerTest{
    static testMethod void testMethod1(){
        Account acc = new Account(Name = 'Test Account');
        insert acc;
        
        Contact con = new Contact(LastName = 'Test Contact',
                                 AccountId = acc.Id);
        insert con;
    Id recordId = acc.Id;
        RestRequest request = new RestRequest();
        request.requestUri = 'https://mydomainalv-dev-ed.my.salesforce.com/servicer/apexrest/Accounts/'+
            recordId + '/contacts';
        request.httpMethod = 'Get';
        RestContext.request = request;
        
        Account thisAccount = AccountManager.getAccount();
        
        system.assert(thisAccount !=null);
        system.assertEquals('Test Account', thisAccount.Name);
        
        
        
    }
    
    
}


try this guys :)
 
Alister TylerAlister Tyler
I think the challenge is fundamentally flawed.....it asks you to return an Account object but also specifies that it wants the contact info. However, the list of contact objects are not part of the Account object
Celebrities Bio and Networth (https://celebsnetworthbio.com)
Alizey KhanAlizey Khan
Thanks Sandeep For Your Solution. It Has Solved My Problem https://leafletoffers.com/
Josh JoshuaJosh Joshua
Prashant I implemented your solution. (https://networthjournal.com/) Thanks man.
Rakesh PRakesh P
Issue is with test data used by the assessment challenge. Check challenge log, you will find "System.AssertException: Assertion Failed: Query for acctWithContacts returned no contacts." 
Find the accountid used in same log and add one test contact for that account . Rerun your challenge. 
Vedika GhaiVedika Ghai
I am getting the following error even after trying many solutions given above:

System.AssertException: Assertion Failed: Query for acctWithContacts returned no contacts
Alfio Alessandro Pisano 9Alfio Alessandro Pisano 9
What Rakesh wrote is correct, by running the challenge and then looking at the log, you will see that demo code is failing on the assertion due to no contacts linked to the account used in the test. Simply pick the SF ID of the account used by challenge test, enter a new contact and then re-run the challenge. You'll pass it.
Sunitha KolliSunitha Kolli
Try this Code 


@RestResource(urlMapping='/Accounts/*/contacts')
global with sharing class AccountManager {
    @HttpGet
    global static Account getAccount(){
        RestRequest req = RestContext.request;
        String accId = req.requestURI.substringBetween('Accounts/','/contacts');
        Account acc = [SELECT Id, Name,(SELECT Id, Name FROM Contacts) 
                       FROM Account WHERE Id = :accId];
        return acc;
    }

}


@isTest
private class AccountManagerTest {
    @isTest static void testAccountManager() {
         Id recordId = getTestAccountId();
        RestRequest request = new RestRequest();
        request.requestURI = 'https://ap5.salesforce.com/services/apexrest/Accounts/'+recordId +'/contacts';
        request.httpMethod= 'GET';
        RestContext.request = request;
        Account acc = AccountManager.getAccount();
        System.assert(acc != null);
        
    }
    private static Id getTestAccountId(){
        Account acc = new Account(Name = 'TestAcc2');
        Insert acc;
        Contact con = new Contact(LastName = 'TestCont2', AccountId = acc.Id);
        insert con;
        return acc.Id;
        
    }

}
 
Pratapsinh Desai 11Pratapsinh Desai 11
I am getting error as-
Executing the 'AccountManager' method failed. Either the service isn't configured with the correct urlMapping, is not global, does not have the proper method name or does not return the requested account and all of its contacts.

MY CODE IS:

@RestResource(urlMapping='/Accounts/*/contacts')
global with sharing class AccountManager {
    @HttpGet
    global static Account getAccount() {
        RestRequest request = RestContext.request;
        // grab the caseId from the end of the URL
        String accountId = request.requestURI.substringBetween('Accounts/','/contacts');
        Account result = [SELECT Id, Name,(Select Id, Name from Contacts) from Account where Id=:accountId];
        return result;
    }
}



// TEST CLASS


@IsTest
private class AccountManagerTest {
    @isTest static void testGetContactsByAccountId() {
        Id recordId = createTestRecord();
        // Set up a test request
        RestRequest request = new RestRequest();
        request.requestUri =
            'https://adventsoftware-dev-ed.lightning.force.com/services/apexrest/Accounts/'+recordId+'/contacts';
        request.httpMethod = 'GET';
        RestContext.request = request;
        // Call the method to test
        Account thisAccount = AccountManager.getAccount();
        // Verify results
        System.assert(thisAccount != null);
        System.assertEquals('Test record', thisAccount.Name);
    }
    // Helper method
    static Id createTestRecord() {
        // Create test record
        Account AccountTest = new Account(
            Name='Test record');
        insert accountTest;
        
        Contact contactTest = new Contact(
            FirstName='Sayali',
            LastName='Desai',
            AccountId=accountTest.Id
        );
        insert contactTest;
        return accountTest.Id;
    }          
}
 
Stéphane PRINStéphane PRIN
After long investigations,
i've got the same message
And in logs we can see : "System.AssertException: Assertion Failed: Query for acctWithContacts returned no contacts"
So i check the Account ID that generate the error
I add manually a Contact to this Account
And when i retry to pass the challenge ... IT WORKS :)
I hope this will help you
David NuñezDavid Nuñez
Thanks @Stéphane PRIN!! 
Zac FowlerZac Fowler
You may have an Account with zero (0) related Contacts causing an assert to fail during the challenge verification.

This is the extended version of @Stéphane PRIN's answer.

If like me, you programmatically created Accounts without Contacts in earlier Trailhead work, this may be another reason for the error showing up.

In the developer console, open the RAW LOG when attempting to pass the challenge. This will show you what is being executed behind the scenes to check your work.  You'll see lines like these:
// snip snip
1  Execute Anonymous: // Creates sample records:
2  Execute Anonymous: Account parentAccount = new Account(Name = 'TestAccount');
3  Execute Anonymous: insert parentAccount;
4  Execute Anonymous: Contact childContact = new Contact(LastName = 'ChildContact', AccountId = parentAccount.Id);
5  Execute Anonymous: insert childContact;
6  Execute Anonymous: 
7  Execute Anonymous: for (Account acctWithContacts: [SELECT Id, (SELECT Id FROM Contacts) FROM Account]) { 
8  Execute Anonymous:     System.assert(acctWithContacts.contacts.size() > 0, 'Query for acctWithContacts returned no contacts');
9  Execute Anonymous: 
10 Execute Anonymous:     RestRequest req = new RestRequest(); 
11 Execute Anonymous:     req.requestUri = '/services/apexrest/Accounts/' + acctWithContacts.Id + '/contacts'; 
12 Execute Anonymous:     req.httpMethod = 'GET'; 
13 Execute Anonymous:     RestContext.request = req; 
14 Execute Anonymous:     Account accountFromRestCall = AccountManager.getAccount(); 
15 Execute Anonymous:     Map<Id, Contact> contacts = new Map<Id, Contact>([SELECT Id FROM Contact WHERE accountId = :acctWithContacts.Id]); 
16 Execute Anonymous:     System.assert(contacts.containsKey(accountFromRestCall.contacts[0].Id), 'accountFromRestCall does not return contacts.'); 
17 Execute Anonymous:     
18 Execute Anonymous:     break; 
19 Execute Anonymous: }
// snip snip
(Line numbers added for reference only)

In this snip, line 8 fails the assert when an Account with 0 Contacts shows up.  You can take the code from the raw log, concat the Account ID to the assert failure string, and repeatedly test in the developer anonymous execution tool to identify which Account objects are causing the failure.  Simply remove the offending Account objects, or add a related Contact record to any with 0 Contacts.

Of course, you could also run a report and find Accounts with 0 Contacts, but you're a programmer.  You prefer debugging statements anyway.

For your convenience, here is the code that I used. Open your Debug -> Open Execute Anonymous Window from the developer console, paste this in, and find out which Account has 0 Contacts.  Once you fix it up you can continue the challenge using any of the solutions above!
 
 // Repurposing the original code
  Account parentAccount = new Account(Name = 'TestAccount');
 insert parentAccount;
 Contact childContact = new Contact(LastName = 'ChildContact', AccountId = parentAccount.Id);
 insert childContact;
 
 for (Account acctWithContacts: [SELECT Id, (SELECT Id FROM Contacts) FROM Account]) { 
     // Concat the ID for the offending Account object
     System.assert(acctWithContacts.contacts.size() > 0, 'Query for acctWithContacts returned no contacts ' + acctWithContacts.Id);
 
     RestRequest req = new RestRequest(); 
     req.requestUri = '/services/apexrest/Accounts/' + acctWithContacts.Id + '/contacts'; 
     req.httpMethod = 'GET'; 
     RestContext.request = req; 
     Account accountFromRestCall = AccountManager.getAccount(); 
     Map<Id, Contact> contacts = new Map<Id, Contact>([SELECT Id FROM Contact WHERE accountId = :acctWithContacts.Id]); 
     System.assert(contacts.containsKey(accountFromRestCall.contacts[0].Id), 'accountFromRestCall does not return contacts.'); 
     
     break; 
 }

Thanks @Stéphane PRIN for the original direction digging into logs.

Enjoy!
Gnanakumar InbasekaranGnanakumar Inbasekaran
If you ever done ProcessAutomation Challenge, you may have restriction on BillingState and ShippingState while creating Account Records.
Look at your Test Log while clicking the "Check Challenge button". The Test log shows the actual error. In my case I disabled those Validation Rules and it worked out. So the point is, CHECK YOUR TEST LOG WHILE VALIDATING THE CHALLENGE. THAT WILL GIVE SPECIFIC INFORMATION or ERROR.
Avinash Gadgil 7Avinash Gadgil 7
The Following Code Worked For Me----

****AccountManager Apex Class

@RestResource(urlMapping='/Accounts/*/contacts')
    global with sharing class AccountManager {
        @HttpGet
        /*
        global static List<Contact> getAccount() {
            RestRequest req = RestContext.request;
            String accId = req.requestURI.substringBetween('Accounts/', '/contacts');
            Account acc = [SELECT Id, Name, (SELECT Id, Name FROM Contacts) FROM Account WHERE Id = :accId];
            system.debug(acc);
            system.debug(acc.Contacts);
            return acc.Contacts;
        }
        */
        global static Account getAccount() {
            RestRequest req = RestContext.request;
            String accId = req.requestURI.substringBetween('Accounts/', '/contacts');
            Account acc = [SELECT Id, Name, (SELECT Id, Name FROM Contacts) FROM Account WHERE Id = :accId];
            system.debug(acc);
            system.debug(acc.Contacts);
            return acc;
        }
    }



***** AccountManagerTest Test Class

@isTest
private class AccountManagerTest {
    @isTest static void testAccountManager() {
        Id recordId = createTestRecord();
        Contact Cont1 = new Contact();
        Cont1.LastName = 'ABC';
        Cont1.AccountId = recordId ;
        insert Cont1;
        Contact Cont2 = new Contact();
        Cont2.LastName = 'XYZ';
        Cont2.AccountId = recordId ;
        insert Cont2 ;
        RestRequest request = new RestRequest();
        request.requestUri =
            'https://cunning-hawk-r6y0ew-dev-ed.lightning.force.com/services/apexrest/Accounts/'+recordId+'/contacts';
        request.httpMethod = 'GET';
        RestContext.request = request;
       Account lst = AccountManager.getAccount();
       /* Tried to return Contact List but failed Trailhead Verification
       List<Contact> lst = new List<Contact>();
       lst = AccountManager.getAccount();
       */
    }
    static Id createTestRecord() {
        Account accTest = new Account(Name='Test Record');
        insert accTest ;
        return accTest.Id;
    }          
}

1) Just change base Url in request.requestUri step (Your Org Api)
2) Make Sure you added two remote sites given in site settings in step one of challenge
3) Run Test class once before checking challenge
4) Still if you are getting error try to create new playground or remove any custom fields that are mandatory on account or contact object, also check validation rules if any that are preventing from creating test account or contact

Mark as best answer if you complete challenge.
Thanks