はじめに
こんなJSONをかえすAPIを想定しています
こんなJSONでレスポンスがきたら
[
{"name": "general", "members": ["D29GZBAFQ", "D29RJ3PAG"]},
{"name": "random", "members": ["D29GZBJBQ", "D29RJ3PBG", "D29RJ3PCG"]}
]
したいこと
APIからJSONでデータを取得した時に、メソッドチェーンでアクセスしできたらいいなー
こんなかんじでアクセスできたら楽だろうなーと思って作ってみました
コンソール
client = Api::Client.new(url)
# チャンネルのレスポンス
client.result.channels # => [
# {"name": "general", "members": ["D29GZBAFQ", "D29RJ3PAG"]},
# {"name": "random", "members": ["D29GZBJBQ", "D29RJ3PBG", "D29RJ3PCG"]}
# ]
# チャンネルに登録しているメンバーID
client.result.channels.first.members # => ["D29GZBJBQ", "D29RJ3PBG", "D29RJ3PCG"]
現状はこんなかんじ
RubyでAPIを使う時の一般的な例
APIを叩くスクリプト
response_json = open(url).read
response_hash = JSON.parse(res)
response_hash.first["members"] # => ["D29GZBJBQ", "D29RJ3PBG", "D29RJ3PCG"]
したいこと
# これがしたい
response_hash.first.members # => エラー
JSON.parseはHashを返すので、メソッドチェーンできずに失敗します
実装
api.rb
require 'open-uri'
require 'json'
class Hash
# ここが実装のきもです。
# Api::Client.new(url).resultはHashインスタンスを返しますが、
# Hashインスタンスに対して`name`などのHashのkeyを呼んだ時に
# self[:name]を返します
def method_missing(name)
return self[name].extend Hash if key? name
self.each { |k, v| return v if k.to_s.to_sym == name }
super.method_missing(name)
end
end
module Api
class Client
attr_accessor :result
def initialize(url)
response = request(url)
@result = parse(response)
end
private
def request(url)
open(url).read
rescue SocketError => e
puts "URLがちがうZE"
end
def parse(res)
JSON.parse(res)
rescue JSON::ParserError => e
puts 'JSONじゃないZE'
{}
end
end
end
できました
SlackAPIを叩いて、randomチャネルに登録しているユーザIDを取得してみます
コンソール
# このURLにアクセスしたい。今回はslackAPI
token = ENV['SLACK_TOKEN']
url = 'https://slack.com/api/channels.list?token=#{token}&pretty=1'
require '上記のファイルパス'
client = Api::Client.new(url)
# チャンネルのレスポンス
puts client.result.channels
# チャンネルに登録しているメンバーID
puts client.result.channels.first.members
実行結果
# チャンネルのレスポンス
[
{"name": "general", "members": ["D29GZBAFQ", "D29RJ3PAG"]},
{"name": "random", "members": ["D29GZBJBQ", "D29RJ3PBG", "D29RJ3PCG"]}
]
# チャンネルに登録しているメンバーID
D29GZBJBQ
D29RJ3PBG
D29RJ3PCG
まとめ
SlackとかGithubのAPIで面白いもの作れそうですね!