Search code examples
rubymonkeypatchingiso8601ruby-grape

How to make all Time outputs be ISO 8601 in Ruby + Grape API


I've been looking around for the easiest solution to convert all Datetime values to ISO 8601 when sending them to a specific requester from an API. I was able to monkey patch Time#to_json with the following:

class Time
  def to_json(options = {})
    self.iso8601.to_json
  end
end

And require the file in the before callback of Grape when params showed the request was coming from the desired location.

Is this the best way to accomplish this? Could I instead be doing something in the after callback of Grape to loop through my data and convert the values there? Monkey patching Time#to_json gets the job done, but feels funny to me. Though I am new to Ruby.


Solution

  • Are you using Grape Entity to expose your models? If you're using it then you can define a reusable formatter like this:

    module ApiHelpers
      extend Grape::API::Helpers
    
      Grape::Entity.format_with :iso8601 do |date|
        date.iso8601 if date
      end
    end
    

    Then, you can use this formatter in all your entities:

    module Entities
      class MyModel < Grape::Entity
        expose :updated_at, format_with: :iso8601
      end
    
      class AnotherModel < Grape::Entity
        expose :created_at, format_with: :iso8601
      end
    end
    

    But if you're not using Grape Entity... well, I think you should. :)

    PS.: All examples I showed here were extracted from Grape Entity documentation. https://github.com/ruby-grape/grape-entity