数週間前に、
Gauges APIを公開しました。 既に存在する
Gaugesにもかかわらず、APIを作成する際にはかなりの作業がありました。 詳細を詳細に理解する必要があります。
1. API作成中にドキュメントを書く
APIの準備がほぼ完了した後、ドキュメントの準備を間違えました。 問題は、ドキュメントがひどいことです。 APIをリリースしても問題ない場合、このルーチンを後で使用すると、作業が二重に困難になります。 幸いなことに、これを経験した
人たちがいました。
2.一定であること
APIドキュメントの作成中、多くの矛盾する点に気付きました。 たとえば、ある場所ではハッシュを返し、他の場所では配列を返しました。 問題を理解し、いくつかのルールを作成し始めました。
配列/ハッシュの問題を解決するために、答えとして常にハッシュを返すことにしました。 これは、将来のタスクに焦点を合わせた最も柔軟なソリューションです。 サービスからの応答を変換したり、APIの新しいバージョンをリリースしたりすることなく、新しいキーを導入することができました。
配列をハッシュに置き換えると、キーを持つ配列の名前空間が必要になります。 さらに、すべてが独自の名前空間を持っているわけではないことに気付きました。 そして再び、私たちはルールを思いつきました。 この場合、すべての最上位オブジェクトには名前空間が必要ですが、これらのオブジェクトの子または複数のオブジェクトのセットには名前空間は必要ありません。
{users:[{user:{...}}, {user:{...}}]} // {users:[{...}, {...}]} // {username: 'jnunemaker'} // {user: {username:'jnunemaker'}} //
さて、あなたはポイントを得る。 一貫性が重要です。 常に1つの形式に従う必要があります。
3. URLを提供する
私のオープンソースの仕事のほとんどは、さまざまなAPIをラップしています。 そして、一つのことは私をたくさん悩ましました、それはURLを生成していました。 各リソースは、それにとって重要なURLを知っている必要があります。 たとえば、ゲージのユーザーには、いくつかのデータを取得するために呼び出すことができるいくつかのURLがあります。
{ "user": { "name": "John Doe", "urls": { "self": "https://secure.gaug.es/me", "gauges": "https://secure.gaug.es/gauges", "clients": "https://secure.gaug.es/clients" }, "id": "4e206261e5947c1d38000001", "last_name": "Doe", "email": "john@doe.com", "first_name": "John" } }
前のJSONは/ meリソースからの応答です。 認証されたユーザーに関するデータと、自身の更新(自己)、すべての統計(/ゲージ)の受信、およびすべてのAPIクライアント(/クライアント)の受信のためのURLを返します。 次のリクエストが/ゲージであるとします。 各ゲージ(統計)は、さらに情報を得るためにさらにいくつかのアドレスを返します。
{ "gauges": [ { // various attributes "urls": { "self":"https://secure.gaug.es/gauges/4ea97a8be5947ccda1000001", "referrers":"https://secure.gaug.es/gauges/4ea97a8be5947ccda1000001/referrers", "technology":"https://secure.gaug.es/gauges/4ea97a8be5947ccda1000001/technology", // ... etc }, } ] }
これはその価値を証明すると思います。 そして、これがうまくいくかどうかは、将来的に見ていきます。
4.レポート
最後に、コントローラーまたはget / post / putシナトラブロックのto_jsonと彼の友人を使用しないでください。 メソッド、:except 、: only、または他のオプションを指定してto_jsonの呼び出しを開始した後、これをすべて別のクラスに移動することができます。
ゲージの場合、これらのクラスをプレゼンターと呼びます。 たとえば、これはUserPresenterの簡易バージョンです。
class UserPresenter def initialize(user) @user = user end def as_json(*) { 'id' => @user.id, 'email' => @user.email, 'name' => @user.name, 'first_name' => @user.first_name, 'last_name' => @user.last_name, 'urls' => { 'self' => "
心配する必要はありません。 アプリ/プレゼンターにあるシンプルなハッククラス。 Sinatraアプリで/ meのルートがどのように見えるかの例を次に示します。
get('/me') do content_type(:json) sign_in_required {:user => UserPresenter.new(current_user)}.to_json end
これは、単体テストを使用して詳細な回答を簡単にテストできるようにするシンプルなプレゼンテーションレイヤーです。 また、すべてが正しく機能することを確認する統合テストも1つあります。 この小さな層は新鮮な空気の息吹だと思います。
上記のいずれも衝撃的または刺激的なものではなかったと確信していますが、次回の公開APIのためにこの記事が少し時間を節約することを願っています。