Advanced 25 min read

Review and Refactor

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

  • Review the complete integration across every layer built this module
  • Confirm the contract from Lesson 1 was fully satisfied
  • Apply the full course checklist one final time to a real external integration

Prerequisites: "Test with HttpCalloutMock"

The complete service, assembled

public class CurrencyConversionException extends Exception {}

public class ConversionResponse {
    public Decimal convertedAmount;
    public Decimal rate;
    public String timestamp;
}

public class CurrencyConversionService {
    public Decimal convert(Decimal amountInZar, String targetCurrency) {
        HttpRequest request = new HttpRequest();
        request.setEndpoint('callout:Currency_API/convert?from=ZAR&to=' + targetCurrency + '&amount=' + amountInZar);
        request.setMethod('GET');
        request.setTimeout(5000);

        HttpResponse response;
        try {
            response = new Http().send(request);
        } catch (CalloutException e) {
            throw new CurrencyConversionException('Could not reach the currency service: ' + e.getMessage());
        }

        if (response.getStatusCode() != 200) {
            throw new CurrencyConversionException('Currency API returned status ' + response.getStatusCode());
        }

        ConversionResponse parsed = (ConversionResponse) JSON.deserialize(response.getBody(), ConversionResponse.class);
        return parsed.convertedAmount;
    }
}

Every lesson's piece is present: the contract-matching request (Lessons 1-2), the Named Credential (Lesson 3), typed JSON parsing (Lesson 4), and both categories of error handling (Lesson 5) — one small, complete, well-tested integration.

Checking against Lesson 1's original contract

  • Matches the request shape defined in Lesson 1? Yes — GET, the exact query parameters, in order.
  • Matches the response shape defined in Lesson 1? Yes — ConversionResponse mirrors it field for field.
  • Handles the unrecognized-currency edge case named in Lesson 1? Yes — surfaces as a clear CurrencyConversionException with the API\'s own error detail included.

The full course checklist, one final time

  • Requirements/contract defined precisely before coding? Yes (Lesson 1).
  • Secrets kept out of Apex code? Yes, via Named Credential (Lesson 3).
  • Both failure categories handled distinctly? Yes — API errors and network failures, each clear (Lesson 5).
  • Custom exception with a clear message? Yes, CurrencyConversionException (Lesson 5).
  • Comprehensive tests, including both failure paths? Yes (Lesson 6).

This closes out every "single external system" integration project this course will build — the next modules move into asynchronous Apex, where a callout's synchronous 10-second limit (Lesson 1's opening constraint) finally gets a real alternative.

Exercise

As a comment, name the one requirement from Lesson 1's contract this final review confirms was satisfied, that you find most important, and why.

Show hint

Pick one from the "checking against the contract" list and justify your choice.

APEX

Review and Refactor Quiz

1. What does the next part of the course move into, building on this module's callout foundation?

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

The closing lesson reviews the entire CurrencyConversionService feature against Lesson 1's original contract and this course's accumulated discipline.