When working with external APIs, we often find ourselves tiptoeing around unpredictable behavior, timeouts, missing data, or malformed responses. In such cases, the goal is not always to raise an exception, but to fail gracefully and move on to the next fallback option.

In this post, we’ll examine a common pattern for safely extracting data from a JSON API response in Ruby without raising errors and explore how to make it clean, readable, and maintainable.

Cleaning It Up:

def fetch_coords_from_api
  api_url = "some_api_url"
  params = { api_key: ENV["API_KEY"] }

  response = ApiClient.new(api_url, params).get
  return nil unless response&.body

  json = parse_json(response.body)
  return nil unless json.is_a?(Hash)

  addresses = json["result"]
  return nil unless addresses.is_a?(Array) && addresses.any?

  address = addresses.find { |add| add["zip"] == zip }
  return nil unless address

  lat = address["latitude"]
  lng = address["longitude"]

  lat && lng ? [lat, lng] : nil
end

private
def parse_json(body)
  JSON.parse(body)
rescue JSON::ParserError
  nil
end

Why This Version Is Better

1. Safe Navigation with &.

We avoid NoMethodError by using response&.body, which prevents calling .body on nil.

2. Robust JSON Parsing

We isolate the potentially dangerous JSON.parse in its own method and rescue JSON::ParserError internally, keeping the main method clean.

3. Clear Intent with Guard Clauses

We use return nil unless for fast exits, keeping the method linear and readable.

4. Simple, Predictable Return Value

We ensure the method only returns either a [latitude, longitude] array or nil, never a half-complete or broken object.

Need Help With Ruby On Rails Development?

Work with our skilled Ruby on Rails developers to accelerate your project and boost its performance.

Hire Ruby on Rails Developer

Support On Demand!

Related Q&A