ApiStruct consists of two main interfaces: ApiStruct::Client and ApiStruct::Entity. The ApiStruct::Client class is aimed at using the same interface for describing requests to different APIs. The ApiStruct::Entity enables you to use ApiStruct clients in ORM-like style.
Installation
Add this line to your application's Gemfile:
gem 'api_struct'
And then execute:
$ bundle
Or install it yourself as:
$ gem install api_struct
Usage
Initialize APIs routes:
ApiStruct::Settings.configure do |config|
  config.endpoints = {
    first_api: {
      root: 'http://localhost:3000/api/v1',
      headers: {
        'content-type': 'application/json',
        'Authorization': 'Bearer TOKEN'
      }
    },
    second_api: {
      root: 'http://localhost:3001/api/v1',
      # etc...
    }
  }
end
Client
Endpoint wrapper
class PostsClient < ApiStruct::Client
  first_api :posts
  def show(id)
    get(id)
  end
  def index
    get
  end
  def user_posts(user_id, post_id = nil)
    get(post_id, prefix: [:users, user_id]) 
    # alias: 
    # get(post_id, prefix: '/users/:id', id: user_id)
  end
  def custom_path(user_id)
    get(path: 'users_posts/:user_id', user_id: user_id)
  end
end
Usage:
PostsClient.new.get(1) # -> /posts/1
Returns Either monad
# => Right({:id=>1, :title=>"Post"})
Other methods from sample:
post_client = PostsClient.new
post_client.index            # -> /posts 
post_client.user_posts(1)    # -> /users/1/posts
post_client.user_posts(1, 2) # -> /users/1/posts/2
post_client.custom_path(1)   # -> /users_posts/1/
Entity
Response serializer
class User < ApiStruct::Entity
  client_service UsersClient
  client_service AuthorsClient, prefix: true, only: :index
  # alias: 
  # client_service AuthorsClient, prefix: :prefix, except: :index
  attr_entity :name, :id
end
class UsersClient < ApiStruct::Client
  first_api :users
  def show(id)
    get(id)
  end
end
class AuthorsClient < ApiStruct::Client
  first_api :authors
  def index
    get
  end
end
Usage:
user = User.show(1)
# => {"id"=>1, "name"=>"John"}
Call methods from prefixed clients:
users = User.
# or
# users = User.prefix_index
Response serializers with related entities:
class Network < ApiStruct::Entity
  client_service NetworkClient
  attr_entity :name, :id
  attr_entity :state, &:to_sym
  has_entity :super_admin, as: User
end
class NetworkClient < ApiStruct::Client
  first_api :networks
  def show(id)
    get(id)
  end
end
Usage:
network = Network.show(1)
# => {"id"=>1, "name"=>"Main network", "state"=>"active", "super_admin"=>{"id"=>1, "name"=>"John"}}
network.state
# => :active
Dynamic headers:
class Auth
  def self.call
    # Get a token..
  end
end
class AuthHeaderValue
  def self.call
    { "Authorization": "Bearer #{Auth.call}" }
  end
end
class PostClient < ApiStruct::Client
  first_api :posts
  def update(id, post_data)
    put(id, json: post_data, headers: AuthHeaderValue.call)
  end
end
Contributing
Bug reports and pull requests are welcome on GitHub at https://github.com/rubygarage/api_struct.
License
The gem is available as open source under the terms of the MIT License.