Coder Social home page Coder Social logo

garage_client's Introduction

GarageClient Build Status

GarageClient is a simple Ruby library to provide a primitive client interface to the Garage application API.

Install

Install from rake command:

$ bundle install
$ rake install

or modify Gemfile in your application and invoke bundle install.

# Gemfile
gem "garage_client"

Usage

Here are quick examples.

Client initialization

require "garage_client"

# First, you have to create a GarageClient::Client with an access token.
# You can get `YOUR_ACCESS_TOKEN` with OAuth 2.0 flow.
client = GarageClient::Client.new(access_token: YOUR_ACCESS_TOKEN)

Read from Garage application

# GET https://garage.example.com/v1/recipes
client.get("/recipes")

# GET https://garage.example.com/v1/recipes?fields=id,name,ingredients
client.get("/recipes", fields: "id,name,ingredients")

# GET https://garage.example.com/v1/me
user = client.get("/me")

# GET https://garage.example.com/v1/users/:user_id/recipes?fields=__default__,user[id,name]
client.get("/users/#{user.id}/recipes", fields: "__default__,user[id,name]")

Write to Garage application

# POST https://garage.example.com/v1/suggestions
client.post("/suggestions", message: "suggestion message")

# POST https://garage.example.com/v1/users/:user_id/bookmark_tags with JSON {"name":"tag name"}
bookmark_tag = client.post("/users/#{user.id}/bookmark_tags", name: "tag name")

# PUT https://garage.example.com/v1/bookmark_tags/:id with JSON {"name":"new tag name"}
client.put("/bookmark_tags/#{bookmark_tag.id}", name: "new tag name")

# DELETE https://garage.example.com/v1/bookmark_tags/:id
client.delete("/bookmark_tags/#{bookmark_tag.id}")

Response

# `.get` method returns a GarageClient::Response of a resource.
user = client.get("/me")
user.id
user.url
user.name

# `.get` method also returns a GarageClient::Response of an array of resources.
# In this case, the response object can respond to `.total_count` method.
recipes = client.get("/recipes")
recipes.total_count
recipes[0].id
recipes[0].name

# While Garage application API returns all default properties, some additional properties are not included in them.
# You can specify the returned properties by `?fields=...` URI query parameters.
recipes = client.get("/recipes", fields: "__default__,user")
recipes[0].id
recipes[0].name
recipes[0].user.id
recipes[0].user.url
recipes[0].user.name

# `.post` method also returns a GarageClient::Response of the newly created resource.
suggestion = client.post("/suggestions", message: "suggestion message")
suggestion.message

Configuration

There are the following options:

  • adapter - faraday adapter for http client (default: :net_http)
  • cacher - take a cacher class in which caching logic is defined (default: nil)
  • name - Client's application name, which is embedded in User-Agent by default (default: nil. For Rails, Rails.application.class.parent_name.underscore is set by default.)
    • name must be configured globally.
  • headers - default http headers (default: { "Accept" => "application/json", "User-Agent" => "garage_client #{VERSION} #{name}" })
  • endpoint - Garage application API endpoint (default: nil)
  • path_prefix - API path prefix (default: '/v1')
  • verbose - Enable verbose http log (default: false)
  • tracing - (client instance only) Enable distributed tracing and set a logical name of the down stream service. See detail in "Tracing" section below.

You can configure the global settings:

GarageClient.configure do |c|
  c.endpoint = "http://localhost:3000"
  c.name = 'my-awesome-client'
  c.verbose = true
end

or each GarageClient::Client settings:

client = GarageClient::Client.new(
  adapter: :test,
  headers: { "Host" => "garage.example.com" },
  endpoint: "http://localhost:3000",
  path_prefix: "/v2",
  verbose: true,
)

Exceptions

GarageClient raises one of the following exceptions upon an error. Make sure to always look out for these in your code.

GarageClient::BadRequest
GarageClient::Unauthorized
GarageClient::Forbidden
GarageClient::NotFound
GarageClient::NotAcceptable
GarageClient::Conflict
GarageClient::UnsupportedMediaType
GarageClient::UnprocessableEntity
GarageClient::InternalServerError
GarageClient::ServiceUnavailable
GarageClient::GatewayTimeout

Utility

.properties returns a list of properties of the resource.

user = client.get("/me")
user.properties #=> [:id, :url, :name, :_links]

.links returns a list of link names related to the resource.

user = client.get("/me")
user.properties #=> [:self, :bookmarks, :recipes, ...]
user.links.recipes #=> "https://garage.example.com/v1/users/:user_id/recipes"

Caching

Define a cacher class with your custom caching logic to let it cache response, inheriting GarageClient::Cachers::Base. It must override read_from_cache?, written_to_cache?, key, and store to compose your caching logic.

class MyCacher < GarageClient::Cachers::Base
  private

  def read_from_cache?
    has_get_method? && has_cached_path?
  end

  def written_to_cache?
    read_from_cache?
  end

  def key
    @env[:url].to_s
  end

  def store
    Rails.cache
  end

  def options
    { expires_in: 5.minutes }
  end

  def has_get_method?
    @env[:method] == :get
  end

  def has_cached_path?
    case @env[:url].path
    when %r<^/v1/searches>
      true
    when %r<^/v1/recipes/\d+>
      true
    end
  end
end

GarageClient::Client.new(cacher: MyCacher)

Tracing

GarageClient supports distributed tracing. To enable tracing, specify tracing.tracer option for GarageClient::Client instance. Choose one of supported tracers from below. If you want to add new tracer, please give us a PR.

aws-xray

Bundle aws-xray gem in your Gemfile, then configure GarageClient::Client instance with tracing.service option:

require 'aws/xray/faraday'
GarageClient::Client.new(..., tracing: { tracer: 'aws-xray', service: 'user' })

service will be name of the sub segments.

garage_client's People

Contributors

9toon avatar adorechic avatar eagletmt avatar eisuke avatar gfx avatar k0kubun avatar kaorimatz avatar katsuma avatar l15n avatar mrkn avatar sorah avatar taiki45 avatar uasi avatar yoshiori avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.