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',
      params: { token: 'Default token' }
    }
  }
endClient
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
endUsage:
PostsClient.new.get(1) # -> /posts/1Returns Result monad
# => Success({: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
endclass UsersClient < ApiStruct::Client
  first_api :users
  def show(id)
    get(id)
  end
endclass AuthorsClient < ApiStruct::Client
  first_api :authors
  def index
    get
  end
endUsage:
user = User.show(1)
# => {"id"=>1, "name"=>"John"}Call methods from prefixed clients:
users = User.authors_client_index
# or
# users = User.prefix_indexResponse 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
endclass NetworkClient < ApiStruct::Client
  first_api :networks
  def show(id)
    get(id)
  end
endUsage:
network = Network.show(1)
# => {"id"=>1, "name"=>"Main network", "state"=>"active", "super_admin"=>{"id"=>1, "name"=>"John"}}
network.state
# => :activeDynamic headers:
class Auth
  def self.call
    # Get a token..
  end
endclass AuthHeaderValue
  def self.call
    { "Authorization": "Bearer #{Auth.call}" }
  end
endclass PostClient < ApiStruct::Client
  first_api :posts
  def update(id, post_data)
    put(id, json: post_data, headers: AuthHeaderValue.call)
  end
endContributing
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.
RubyGarage is a leading software development and consulting company in Eastern Europe. Our main expertise includes Ruby and Ruby on Rails, but we successfully employ other technologies to deliver the best results to our clients. Check out our portfolio for even more exciting works!