SlideShare a Scribd company logo
1 of 56
Download to read offline
Data API 勉強会 Vol.1
2014.6.11 @ Co-Edo
YUJI Takayama@Six Apart
About Me
• 名前: 高山 裕司
• 会社: シックス・アパート
• 仕事: Movable Type 全般
• プロダクト・マネージャ
• リード・エンジニア
github.com/yuji
@yuji
Yuji Takayama
Agenda
• Data APIってなに?
• 初めての Data API
• JavaScript ライブラリ
• サインイン 記事の投稿
• こんな使い方も・・・
Data APIって何?
• Movable Type 6 から搭載
• Movable Type に保存されているデー
タを操る
• REST API
• MT のユーザー管理、認証機構を利用
• JavaScript のライブラリを提供
• プラグインで API 自体を拡張可能
• 公開サイトでも、管理サイトでも、別の
アプリケーションとでも
• まだまだ発展途上
なぜ、Data API を
リリースしたのか
• 様々なデバイスの登場
• ダイナミック・コンテンツ
• MT Perl
• ユーザーの役割に応じた画面作り
• 管理画面 は、管理する人が使う
• コンテンツの作成は、 管理画面 である必要は
ない
初めての
Data API
Data API で出来ること
Create Read Update Delete
Entry ○ ○ ○ ○
Comment ○ ○ ○ ○
Trackback ○ ○ ○
User ○ ○
Site(Blog,Website) ○
Category ○
Site Statistics ○
Asset ○
Data API の使い方
http://localhost/mt/mt-data-api.cgi/v1/sites/1
エンドポイント と呼ばれる URL を呼び出す
Data API のスクリプトへのパス
Data API のバージョン
呼び出すメソッドとパラメータ
https://github.com/movabletype/Documentation/wiki/Quick-reference
呼び出し方で処理が変わる
POST GET PUT DELETE
Entry ○ ○ ○ ○
Comment ○ ○ ○ ○
Trackback ○ ○ ○
User ○ ○
Site(Blog,Website) ○
Category ○
Site Statistics ○
Asset ○
同じエンドポイントへのリクエストで変わる
結果は JSON 形式
{!
"url" : "http://localhost/blog/20140609-1/",!
"archiveUrl" : "http://localhost/blog/20140609-1/",!
"name" : "First Website",!
"class" : "website",!
"id" : "1",!
"description" : null!
}
https://github.com/movabletype/Documentation/wiki/Quick-reference
• HTTP(s) を呼び出せれば呼び出し元は
ブラウザだろうが、アプリだろうが、コ
ンソールだろうが、何でもいい
• 戻りは JSON 形式なので、JSON パー
サがある方がラクと言えばラク
サインイン から
記事のポストまで
実
践
ユーザー認証
curl -i -d clientId=test -d username=takayama -d password=password	
http://localhost/cgi-bin/mt/mt-data-api.cgi/v1/authentication -X POST
リクエスト
応答
HTTP/1.1 200 OK	
Date: Mon, 09 Jun 2014 07:01:38 GMT	
Server: Apache/2.2.26 (Unix) mod_ssl/2.2.26 OpenSSL/1.0.1e DAV/2 PHP/5.3.27	
X-content-type: nosniff	
Cache-control: no-cache	
Transfer-Encoding: chunked	
Content-Type: application/json; charset=UTF-8	
X-Pad: avoid browser bug	
!
{"sessionId":"vjqLFlFxEki5ElAHy9DyUe6k3jAuevXJyGdjXk8j","accessToken":"h8YOleAJo
aBkNCJl3kmOgmlsocNo0J5LiwZljAV9","expiresIn":3600,"remember":false}
記事の投稿
curl -i http://localhost/cgi-bin/mt/mt-data-api.cgi/v1/sites/1/entries -X POST	
-H "X-MT-Authorization: MTAuth accessToken=h8YOleAJoaBkNCJl3kmOgmlsocNo0J5LiwZljAV9”	
-d entry="{"status" : "Publish", "title" : "This is test post", "body" :
"Yeah!" }"
リクエスト
応答
HTTP/1.1 200 OK	
Date: Mon, 09 Jun 2014 07:27:00 GMT	
Server: Apache/2.2.26 (Unix) mod_ssl/2.2.26 OpenSSL/1.0.1e DAV/2 PHP/5.3.27	
X-content-type: nosniff	
Cache-control: no-cache	
Transfer-Encoding: chunked	
Content-Type: application/json; charset=UTF-8	
X-Pad: avoid browser bug	
!
{"excerpt":"Yeah!...","date":"2014-06-09T16:27:01u002b09:00","status":"Publish","updatable":true,"author":
{"userpicUrl":null,"id":"1","displayName":"Yuji Takayama"},"comments":[],"allowComments":true,"permalink":"http://localhost/blog/
20140609-1/2014/06/this-is-test-post.html","keywords":"","body":"Yeah!","trackbacks":[],"id":
4,"allowTrackbacks":false,"modifiedDate":"2014-06-09T16:27:01u002b09:00","trackbackCount":0,"blog":{"id":"1"},"categories":[],"tags":
[],"commentCount":0,"assets":[],"basename":"this_is_test_post","createdDate":"2014-06-09T16:27:01u002b09:00","class":"entry","title":"This
is test post","pingsSentUrl":[],"more":"","customFields":[]}% /Users/takayama% curl -
i http://localhost/cgi-bin/mt/mt-data-api.cgi/v1/sites/1/entries -X POST -H "X-MT-Authorization: MTAuth
accessToken=h8YOleAJoaBkNCJl3kmOgmlsocNo0J5LiwZljAV9" -d entry="{"status" : "Publish", "title" : "This is test post", "body" :
"Yeah!" }"
まぁ、無理ですよね
(́・ω・`)
JavaScript
ライブラリ
• REST API の呼び出しをラッピング
• シンプルな実装なので、他のライブラリ
と干渉しにくい
• 他の言語系も順次サポート予定
使い方
var  api  =  new  MT.DataAPI({  
    baseUrl:    "https://your-­‐host/mt/mt-­‐data-­‐api.cgi",  
    clientId:  "your-­‐client-­‐id"  
});  
!
api.listEntries(siteId,  function(response)  {  
    if  (response.error)  {  
        //  Handle  error  
        return;  
    }  
!
    for  (var  i  =  0;  i  <  response.items.length;  i++)  {  
            var  entry  =  response.items[i];  
            //  Render  an  entry  
    }  
});
<script  type=“text/javascript”  src=“http://your-­‐host/path/to/mt-­‐static/
data-­‐api/v1/js/mt-­‐data-­‐api.min.js”></script>
var  api  =  new  MT.DataAPI({  
    baseUrl:    "https://your-­‐host/mt/mt-­‐data-­‐api.cgi",  
    clientId:  "your-­‐client-­‐id"  
});  
!
api.getToken(function(response)  {  
    if  (response.error)  {  
        if  (response.error.code  ===  401)  {  
            //  You  have  not  been  authenticated  yet.  
            location.href  =  api.getAuthorizationUrl(location.href);  
        }  else  {  /*  Handle  error  */  }  
    }  else  {  
        //  You  have  been  authenticated.  
        api.listEntries(siteId,  {status:  'Draft'},  function(response)  {  
            if  (response.error)  {  /*  Handle  error  */  return;  }      
            //  Fetched  a  list  of  drafts.  
            for  (var  i  =  0;  i  <  response.items.length;  i++)  {  
                    var  entry  =  response.items[i];  
                    //  Render  an  entry  
            }  
        });  
    }  
});
サインイン から
記事のポストまで
実
践
MovableType Writer(仮)
https://github.com/movabletype/MovableTypeWriter
• Movable Type powered by
JavaScript
• 記事の投稿に特化した Chrome アプリ
• Data API + jQuery + Bootstrap3
• MIT でフォーク自由
使っているメソッド
• authenticate(サインイン)
• getToken(トークン取得)
• listBlogForUser(権限を持っているサイトの一
覧を取得)
• createEntry(記事の作成)
初期化
    jQuery(document).ready(  function()  {  
      getSettings().then(  
            function(settings)  {  
                if  (!settings  ||  !settings.apipath)  {  
                    return  jQuery('#setting-­‐panel-­‐dialog').modal();  
                }  
!
                api  =  new  MT.DataAPI({  
                    baseUrl:    settings.apipath,  
                    clientId:  "movabletype-­‐writer"  
                });  
!
                doSignIn(settings.username,  settings.password)  
                .then(  loadSiteList  );  
.  
.  
.
初期化
    jQuery(document).ready(  function()  {  
      getSettings().then(  
            function(settings)  {  
                if  (!settings  ||  !settings.apipath)  {  
                    return  jQuery('#setting-­‐panel-­‐dialog').modal();  
                }  
!
                api  =  new  MT.DataAPI({  
                    baseUrl:    settings.apipath,  
                    clientId:  "movabletype-­‐writer"  
                });  
!
                doSignIn(settings.username,  settings.password)  
                .then(  loadSiteList  );  
.  
.  
.
ローカルストレージから、設定内容を読み込む。
設定されていなければ、設定用のダイアログを表示する
初期化
    jQuery(document).ready(  function()  {  
      getSettings().then(  
            function(settings)  {  
                if  (!settings  ||  !settings.apipath)  {  
                    return  jQuery('#setting-­‐panel-­‐dialog').modal();  
                }  
!
                api  =  new  MT.DataAPI({  
                    baseUrl:    settings.apipath,  
                    clientId:  "movabletype-­‐writer"  
                });  
!
                doSignIn(settings.username,  settings.password)  
                .then(  loadSiteList  );  
.  
.  
.Data API のインスタンスを生成する
baseUrl には Data API へのURL
clientId は任意の文字列
初期化
    jQuery(document).ready(  function()  {  
      getSettings().then(  
            function(settings)  {  
                if  (!settings  ||  !settings.apipath)  {  
                    return  jQuery('#setting-­‐panel-­‐dialog').modal();  
                }  
!
                api  =  new  MT.DataAPI({  
                    baseUrl:    settings.apipath,  
                    clientId:  "movabletype-­‐writer"  
                });  
!
                doSignIn(settings.username,  settings.password)  
                .then(  loadSiteList  );  
.  
.  
.
ユーザー認証を行う
その後、サイト一覧を更新する
サインイン
    var  doSignIn  =  function(user,  passwd)  {  
        var  def  =  new  jQuery.Deferred();  
!
        api.authenticate({  username:  user,  password:  passwd  },    
            function(response)  {  
            if  (response.error)  {  
                var  code  =  response.error.code;  
                var  msg;  
                if  (code  ===  404  )  {  
                }  else  if  (code  ===  401  )  {  
                }  else  {  
                }  
                return  def.reject(msg);  
            }  else  {  
                api.storeTokenData(response);  
                return  def.resolve();  
            }  
        });  
!
        return  def.promise();  
    };
サインイン
    var  doSignIn  =  function(user,  passwd)  {  
        var  def  =  new  jQuery.Deferred();  
!
        api.authenticate({  username:  user,  password:  passwd  },    
            function(response)  {  
            if  (response.error)  {  
                var  code  =  response.error.code;  
                var  msg;  
                if  (code  ===  404  )  {  
                }  else  if  (code  ===  401  )  {  
                }  else  {  
                }  
                return  def.reject(msg);  
            }  else  {  
                api.storeTokenData(response);  
                return  def.resolve();  
            }  
        });  
!
        return  def.promise();  
    };
認証用のエンドポイントを呼び出す。
認証エラーは、response.error の有無で判定
認証に成功したら、storeTokenData でセッションデータを保存
サイト一覧の取得
    var  loadSiteList  =  function()  {  
        var  def  =  new  jQuery.Deferred();  
!
        api.listBlogsForUser('me',  function(response)  {  
            if  (response.error)  {  
                var  code  =  response.error.code;  
                var  msg;  
                if  (code  ===  404  )  {  
                }  else  if  (code  ===  403  )  {  
                }  else  {  
                }  
                return  def.reject(msg);  
            }  
!
            var  $blogListBox  =  jQuery('#form-­‐blog-­‐list');  
            response.items.forEach(  function(x,  i)  {  
                $blogListBox.append($('<option>').html(x.name).val(x.id));  
            });  
            $blogListBox.removeAttr('disabled');  
        });  
サイト一覧の取得
    var  loadSiteList  =  function()  {  
        var  def  =  new  jQuery.Deferred();  
!
        api.listBlogsForUser('me',  function(response)  {  
            if  (response.error)  {  
                var  code  =  response.error.code;  
                var  msg;  
                if  (code  ===  404  )  {  
                }  else  if  (code  ===  403  )  {  
                }  else  {  
                }  
                return  def.reject(msg);  
            }  
!
            var  $blogListBox  =  jQuery('#form-­‐blog-­‐list');  
            response.items.forEach(  function(x,  i)  {  
                $blogListBox.append($('<option>').html(x.name).val(x.id));  
            });  
            $blogListBox.removeAttr('disabled');  
        });  
ユーザーが権限を持つサイトの一覧を取得する
エラー 404: サイトが見つからない
エラー: 403: 認証エラー
サイト一覧の取得
    var  loadSiteList  =  function()  {  
        var  def  =  new  jQuery.Deferred();  
!
        api.listBlogsForUser('me',  function(response)  {  
            if  (response.error)  {  
                var  code  =  response.error.code;  
                var  msg;  
                if  (code  ===  404  )  {  
                }  else  if  (code  ===  403  )  {  
                }  else  {  
                }  
                return  def.reject(msg);  
            }  
!
            var  $blogListBox  =  jQuery('#form-­‐blog-­‐list');  
            response.items.forEach(  function(x,  i)  {  
                $blogListBox.append($('<option>').html(x.name).val(x.id));  
            });  
            $blogListBox.removeAttr('disabled');  
        });  
セレクトボックスに読み込んだサイトの一覧を追加
記事の投稿
    jQuery('#button-­‐post').click(  function()  {  
        var  entry  =  {};  
        entry['title']  =  jQuery('#entry-­‐title').val();  
        entry['body']  =  jQuery('#entry-­‐body').code();  
        entry['status']  =  'Publish';  
        var  siteId  =  jQuery('#form-­‐blog-­‐list  option:selected').val();  
        api.getToken(function(response)  {  
            if  (response.error)  {  }  
            api.createEntry(siteId,  entry,  function(response)  {  
                if  (response.error)  {  
                    var  code  =  response.error.code;  
                    var  msg;  
                    if  (code  ===  404  )  {  
                 }  else  if  (code  ===  401  )  {  
                    }  else  if  (code  ===  403  )  {  
                    }  else  {  
                    }  
                }  
            }  
        }  
    }
記事の投稿
    jQuery('#button-­‐post').click(  function()  {  
        var  entry  =  {};  
        entry['title']  =  jQuery('#entry-­‐title').val();  
        entry['body']  =  jQuery('#entry-­‐body').code();  
        entry['status']  =  'Publish';  
        var  siteId  =  jQuery('#form-­‐blog-­‐list  option:selected').val();  
        api.getToken(function(response)  {  
            if  (response.error)  {  }  
            api.createEntry(siteId,  entry,  function(response)  {  
                if  (response.error)  {  
                    var  code  =  response.error.code;  
                    var  msg;  
                    if  (code  ===  404  )  {  
                 }  else  if  (code  ===  401  )  {  
                    }  else  if  (code  ===  403  )  {  
                    }  else  {  
                    }  
                }  
            }  
        }  
    }
エントリーデータをハッシュで作成
記事の投稿
    jQuery('#button-­‐post').click(  function()  {  
        var  entry  =  {};  
        entry['title']  =  jQuery('#entry-­‐title').val();  
        entry['body']  =  jQuery('#entry-­‐body').code();  
        entry['status']  =  'Publish';  
        var  siteId  =  jQuery('#form-­‐blog-­‐list  option:selected').val();  
        api.getToken(function(response)  {  
            if  (response.error)  {  }  
            api.createEntry(siteId,  entry,  function(response)  {  
                if  (response.error)  {  
                    var  code  =  response.error.code;  
                    var  msg;  
                    if  (code  ===  404  )  {  
                 }  else  if  (code  ===  401  )  {  
                    }  else  if  (code  ===  403  )  {  
                    }  else  {  
                    }  
                }  
            }  
        }  
    }
トークンの有効期限が過ぎている場合は、再取得が必要
記事の投稿
    jQuery('#button-­‐post').click(  function()  {  
        var  entry  =  {};  
        entry['title']  =  jQuery('#entry-­‐title').val();  
        entry['body']  =  jQuery('#entry-­‐body').code();;  
        entry['status']  =  'Publish';  
        var  siteId  =  jQuery('#form-­‐blog-­‐list  option:selected').val();  
        api.getToken(function(response)  {  
            if  (response.error)  {  }  
            api.createEntry(siteId,  entry,  function(response)  {  
                if  (response.error)  {  
                    var  code  =  response.error.code;  
                    var  msg;  
                    if  (code  ===  404  )  {  
                 }  else  if  (code  ===  401  )  {  
                    }  else  if  (code  ===  403  )  {  
                    }  else  {  
                    }  
                }  
            }  
        }  
    }
エントリの作成をおこなう
エラー 404: 投稿先のサイトが見つからない
エラー 403: 権限がない
エラー 401: 認証エラー
ユーザー専用
投稿ツール
タイトル
カスタムフィールド
カスタムフィールド
本文
JavaScript
ライブラリ
勘所
API の呼び出しは非同期
初期化パラメータで同期にすることも可能
!
var api = new MT.DataAPI({
clientId: your-client-id ,
baseUrl: https://your-host/your-mt-api.cgi',
async: false
});
認証URL vs 認証呼び出し
ブラウザからの利用であれば、authenticate ではなく、
getAuthorizationUrl を使って MT 標準のサインイン画
面を利用する方がいい(セキュリティ、信頼性)
!
var url = api.getAuthorizationUrl(
https://your-host/your-app/ ) // リダイレクト先
);
クロスドメイン
クロスドメイン間の通信は原則禁止されているので、
適宜 環境変数を設定する
!
少なくとも
DataAPICORSAllowOrigin *
DataAPICORSAllowOrigin http://www.example.com, http://beta.example.com
!
ついでに
DataAPICORSAllowHeaders
DataAPICORSExposeHeaders
DataAPICORSAllowMethods
など
Data API
こんな使い方も
スマートフォンアプリ
• スマフォサイトをウェブアプリとして
• ネイティブアプリから利用して
• Movable Type as Backend Service
Ajax 検索
• インクリメンタルサーチ
• MT-Search.cgi よりも軽量
ページネーション
• 画面のスクロールでインクリメンタルな
読み込み
• 検索結果などページネーション
社内システムなど
• 社内ポータルに、記事作成のインターフェ
イスを用意して、簡単に記事をポスト
• 一般ユーザーは、MTの画面を見る必要
がない
Google Analytics
• MTにGoogle Analyticsの設定があれば
• Data API から Google Analyticsのデー
タを読み込める
Chrome
• タグ・環境変数の検索 by Omnibox
• 再構築の定期実行 by Alarm
• スニペット挿入 by BrowserAction
• 詳しくは、この後のお話で!
Next
Data API…
• 色々まだ足りてないですよね?
• 次以降のリリースで含まれる Data API
の機能をプラグインで随時リリース予定
• 震えて、待て!

More Related Content

What's hot

Hypermedia: The Missing Element to Building Adaptable Web APIs in Rails (増補日本語版)
Hypermedia: The Missing Element to Building Adaptable Web APIs in Rails (増補日本語版)Hypermedia: The Missing Element to Building Adaptable Web APIs in Rails (増補日本語版)
Hypermedia: The Missing Element to Building Adaptable Web APIs in Rails (増補日本語版)Toru Kawamura
 
HTML5でオフラインWebアプリケーションを作ろう
HTML5でオフラインWebアプリケーションを作ろうHTML5でオフラインWebアプリケーションを作ろう
HTML5でオフラインWebアプリケーションを作ろうyoshikawa_t
 
Webフロントエンド開発の最新トレンド - HTML5, モバイル, オフライン
Webフロントエンド開発の最新トレンド - HTML5, モバイル, オフラインWebフロントエンド開発の最新トレンド - HTML5, モバイル, オフライン
Webフロントエンド開発の最新トレンド - HTML5, モバイル, オフラインShumpei Shiraishi
 
Microsoft Graph APIを活用した社内アプリケーション開発
Microsoft Graph APIを活用した社内アプリケーション開発Microsoft Graph APIを活用した社内アプリケーション開発
Microsoft Graph APIを活用した社内アプリケーション開発Yuki Hattori
 
Infrastructure as code for azure
Infrastructure as code for azureInfrastructure as code for azure
Infrastructure as code for azureKeiji Kamebuchi
 
Movable Type as a Playground
Movable Type as a PlaygroundMovable Type as a Playground
Movable Type as a PlaygroundTaku AMANO
 
GoAzure 2015 Azure AD for Developers
GoAzure 2015 Azure AD for DevelopersGoAzure 2015 Azure AD for Developers
GoAzure 2015 Azure AD for Developerskekekekenta
 
IDaaSにSign in with Appleをつないでみた
IDaaSにSign in with AppleをつないでみたIDaaSにSign in with Appleをつないでみた
IDaaSにSign in with AppleをつないでみたNaohiro Fujie
 
Windows Azure Active Directory for your cloud applications
Windows Azure Active Directory for your cloud applicationsWindows Azure Active Directory for your cloud applications
Windows Azure Active Directory for your cloud applicationskekekekenta
 
今更聞けない!?Microsoft Graph で始める Office 365 データ活用と事例の紹介
今更聞けない!?Microsoft Graph で始める Office 365 データ活用と事例の紹介今更聞けない!?Microsoft Graph で始める Office 365 データ活用と事例の紹介
今更聞けない!?Microsoft Graph で始める Office 365 データ活用と事例の紹介Kenichiro Nakamura
 
Data API ことはじめ
Data API ことはじめData API ことはじめ
Data API ことはじめYuji Takayama
 
Azure AD x LINE x Auth0
Azure AD x LINE x Auth0Azure AD x LINE x Auth0
Azure AD x LINE x Auth0Naohiro Fujie
 
Share point開発 ファイル受信
Share point開発 ファイル受信Share point開発 ファイル受信
Share point開発 ファイル受信Akihiro Ehara
 
Service worker が拓く mobile web の新しいかたち
Service worker が拓く mobile web の新しいかたちService worker が拓く mobile web の新しいかたち
Service worker が拓く mobile web の新しいかたちKinuko Yasuda
 
Build insider testingwithvs
Build insider testingwithvsBuild insider testingwithvs
Build insider testingwithvsTomoyuki Iwade
 
AWSを利用したアプリ開発
AWSを利用したアプリ開発AWSを利用したアプリ開発
AWSを利用したアプリ開発Fixel Inc.
 
サーバレスを可能にするAWSサービスの概要
サーバレスを可能にするAWSサービスの概要サーバレスを可能にするAWSサービスの概要
サーバレスを可能にするAWSサービスの概要Fixel Inc.
 
MicrosoftのDID/VC実装概要
MicrosoftのDID/VC実装概要MicrosoftのDID/VC実装概要
MicrosoftのDID/VC実装概要Naohiro Fujie
 

What's hot (20)

Hypermedia: The Missing Element to Building Adaptable Web APIs in Rails (増補日本語版)
Hypermedia: The Missing Element to Building Adaptable Web APIs in Rails (増補日本語版)Hypermedia: The Missing Element to Building Adaptable Web APIs in Rails (増補日本語版)
Hypermedia: The Missing Element to Building Adaptable Web APIs in Rails (増補日本語版)
 
HTML5でオフラインWebアプリケーションを作ろう
HTML5でオフラインWebアプリケーションを作ろうHTML5でオフラインWebアプリケーションを作ろう
HTML5でオフラインWebアプリケーションを作ろう
 
Webフロントエンド開発の最新トレンド - HTML5, モバイル, オフライン
Webフロントエンド開発の最新トレンド - HTML5, モバイル, オフラインWebフロントエンド開発の最新トレンド - HTML5, モバイル, オフライン
Webフロントエンド開発の最新トレンド - HTML5, モバイル, オフライン
 
Microsoft Graph APIを活用した社内アプリケーション開発
Microsoft Graph APIを活用した社内アプリケーション開発Microsoft Graph APIを活用した社内アプリケーション開発
Microsoft Graph APIを活用した社内アプリケーション開発
 
Infrastructure as code for azure
Infrastructure as code for azureInfrastructure as code for azure
Infrastructure as code for azure
 
Movable Type as a Playground
Movable Type as a PlaygroundMovable Type as a Playground
Movable Type as a Playground
 
GoAzure 2015 Azure AD for Developers
GoAzure 2015 Azure AD for DevelopersGoAzure 2015 Azure AD for Developers
GoAzure 2015 Azure AD for Developers
 
IDaaSにSign in with Appleをつないでみた
IDaaSにSign in with AppleをつないでみたIDaaSにSign in with Appleをつないでみた
IDaaSにSign in with Appleをつないでみた
 
Windows Azure Active Directory for your cloud applications
Windows Azure Active Directory for your cloud applicationsWindows Azure Active Directory for your cloud applications
Windows Azure Active Directory for your cloud applications
 
今更聞けない!?Microsoft Graph で始める Office 365 データ活用と事例の紹介
今更聞けない!?Microsoft Graph で始める Office 365 データ活用と事例の紹介今更聞けない!?Microsoft Graph で始める Office 365 データ活用と事例の紹介
今更聞けない!?Microsoft Graph で始める Office 365 データ活用と事例の紹介
 
Data API ことはじめ
Data API ことはじめData API ことはじめ
Data API ことはじめ
 
Mobile Web
Mobile WebMobile Web
Mobile Web
 
Azure AD x LINE x Auth0
Azure AD x LINE x Auth0Azure AD x LINE x Auth0
Azure AD x LINE x Auth0
 
Rest ful api設計入門
Rest ful api設計入門Rest ful api設計入門
Rest ful api設計入門
 
Share point開発 ファイル受信
Share point開発 ファイル受信Share point開発 ファイル受信
Share point開発 ファイル受信
 
Service worker が拓く mobile web の新しいかたち
Service worker が拓く mobile web の新しいかたちService worker が拓く mobile web の新しいかたち
Service worker が拓く mobile web の新しいかたち
 
Build insider testingwithvs
Build insider testingwithvsBuild insider testingwithvs
Build insider testingwithvs
 
AWSを利用したアプリ開発
AWSを利用したアプリ開発AWSを利用したアプリ開発
AWSを利用したアプリ開発
 
サーバレスを可能にするAWSサービスの概要
サーバレスを可能にするAWSサービスの概要サーバレスを可能にするAWSサービスの概要
サーバレスを可能にするAWSサービスの概要
 
MicrosoftのDID/VC実装概要
MicrosoftのDID/VC実装概要MicrosoftのDID/VC実装概要
MicrosoftのDID/VC実装概要
 

Similar to Data api workshop at Co-Edo

初めての Data api cms どうでしょう - 大阪夏の陣
初めての Data api   cms どうでしょう - 大阪夏の陣初めての Data api   cms どうでしょう - 大阪夏の陣
初めての Data api cms どうでしょう - 大阪夏の陣Yuji Takayama
 
初めての Data api
初めての Data api初めての Data api
初めての Data apiYuji Takayama
 
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみたYuki Takei
 
ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用Yatabe Terumasa
 
勉強会force#4 Chatter Integration
勉強会force#4 Chatter Integration勉強会force#4 Chatter Integration
勉強会force#4 Chatter IntegrationKazuki Nakajima
 
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/WebサービスにアクセスするEWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/WebサービスにアクセスするKiyoshi Sawada
 
Azure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライAzure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライMasanobu Sato
 
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/WebサービスにアクセスするEWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/WebサービスにアクセスするKiyoshi Sawada
 
Pro aspnetmvc3framework chap19
Pro aspnetmvc3framework chap19Pro aspnetmvc3framework chap19
Pro aspnetmvc3framework chap19Hideki Hashizume
 
Alfresco勉強会20120829: やさしいShareダッシュレットの作り方
Alfresco勉強会20120829: やさしいShareダッシュレットの作り方Alfresco勉強会20120829: やさしいShareダッシュレットの作り方
Alfresco勉強会20120829: やさしいShareダッシュレットの作り方linzhixing
 
Chrome Extensionsの基本とデザインパターン
Chrome Extensionsの基本とデザインパターンChrome Extensionsの基本とデザインパターン
Chrome Extensionsの基本とデザインパターンYoichiro Tanaka
 
[東京] JapanSharePointGroup 勉強会 #2
[東京] JapanSharePointGroup 勉強会 #2[東京] JapanSharePointGroup 勉強会 #2
[東京] JapanSharePointGroup 勉強会 #2Atsuo Yamasaki
 
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...Shotaro Suzuki
 
20150207コデアルエンジニア学生向けハッカソン就活イベント発表資料
20150207コデアルエンジニア学生向けハッカソン就活イベント発表資料20150207コデアルエンジニア学生向けハッカソン就活イベント発表資料
20150207コデアルエンジニア学生向けハッカソン就活イベント発表資料codeal
 
API Gateway + LambdaでLINE通知サービス構築
API Gateway + LambdaでLINE通知サービス構築API Gateway + LambdaでLINE通知サービス構築
API Gateway + LambdaでLINE通知サービス構築Ken'ichirou Kimura
 
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回Naoyuki Yamada
 
エンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSエンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSAyumi Goto
 

Similar to Data api workshop at Co-Edo (20)

初めての Data api cms どうでしょう - 大阪夏の陣
初めての Data api   cms どうでしょう - 大阪夏の陣初めての Data api   cms どうでしょう - 大阪夏の陣
初めての Data api cms どうでしょう - 大阪夏の陣
 
初めての Data api
初めての Data api初めての Data api
初めての Data api
 
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
自作node.jsフレームワークとnginxを使ってラジオサイトを作ってみた
 
ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用ソーシャルアプリ勉強会(第一回資料)配布用
ソーシャルアプリ勉強会(第一回資料)配布用
 
勉強会force#4 Chatter Integration
勉強会force#4 Chatter Integration勉強会force#4 Chatter Integration
勉強会force#4 Chatter Integration
 
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/WebサービスにアクセスするEWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
 
Azure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライAzure で Serverless 初心者向けタッチ&トライ
Azure で Serverless 初心者向けタッチ&トライ
 
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/WebサービスにアクセスするEWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
EWD 3トレーニングコース#33 ewd-xpressアプリケーションからREST/Webサービスにアクセスする
 
Pro aspnetmvc3framework chap19
Pro aspnetmvc3framework chap19Pro aspnetmvc3framework chap19
Pro aspnetmvc3framework chap19
 
Alfresco勉強会20120829: やさしいShareダッシュレットの作り方
Alfresco勉強会20120829: やさしいShareダッシュレットの作り方Alfresco勉強会20120829: やさしいShareダッシュレットの作り方
Alfresco勉強会20120829: やさしいShareダッシュレットの作り方
 
Chrome Extensionsの基本とデザインパターン
Chrome Extensionsの基本とデザインパターンChrome Extensionsの基本とデザインパターン
Chrome Extensionsの基本とデザインパターン
 
Connect with Data API
Connect with Data APIConnect with Data API
Connect with Data API
 
Ajax 応用
Ajax 応用Ajax 応用
Ajax 応用
 
[東京] JapanSharePointGroup 勉強会 #2
[東京] JapanSharePointGroup 勉強会 #2[東京] JapanSharePointGroup 勉強会 #2
[東京] JapanSharePointGroup 勉強会 #2
 
後期03
後期03後期03
後期03
 
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...Let's build a simple app with  .net 6 asp.net core web api, react, and elasti...
Let's build a simple app with .net 6 asp.net core web api, react, and elasti...
 
20150207コデアルエンジニア学生向けハッカソン就活イベント発表資料
20150207コデアルエンジニア学生向けハッカソン就活イベント発表資料20150207コデアルエンジニア学生向けハッカソン就活イベント発表資料
20150207コデアルエンジニア学生向けハッカソン就活イベント発表資料
 
API Gateway + LambdaでLINE通知サービス構築
API Gateway + LambdaでLINE通知サービス構築API Gateway + LambdaでLINE通知サービス構築
API Gateway + LambdaでLINE通知サービス構築
 
データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回データマイニング+WEB勉強会資料第6回
データマイニング+WEB勉強会資料第6回
 
エンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJSエンタープライズ分野での実践AngularJS
エンタープライズ分野での実践AngularJS
 

More from Yuji Takayama

Movable Type 7 のすべて
Movable Type 7 のすべてMovable Type 7 のすべて
Movable Type 7 のすべてYuji Takayama
 
詳説 Movable type 7
詳説 Movable type 7詳説 Movable type 7
詳説 Movable type 7Yuji Takayama
 
詳説 Data api mtddc 拡張版 v3対応
詳説 Data api mtddc 拡張版   v3対応詳説 Data api mtddc 拡張版   v3対応
詳説 Data api mtddc 拡張版 v3対応Yuji Takayama
 
Movable Type for AWS Hands-on
Movable Type for AWS Hands-onMovable Type for AWS Hands-on
Movable Type for AWS Hands-onYuji Takayama
 
Data API + AWS = (CMS どうでしょう 札幌編)
Data API + AWS =  (CMS どうでしょう 札幌編)Data API + AWS =  (CMS どうでしょう 札幌編)
Data API + AWS = (CMS どうでしょう 札幌編)Yuji Takayama
 
Movable Type for AWS - JAWS-UG 沖縄 CMS祭り!
Movable Type for AWS - JAWS-UG 沖縄 CMS祭り!Movable Type for AWS - JAWS-UG 沖縄 CMS祭り!
Movable Type for AWS - JAWS-UG 沖縄 CMS祭り!Yuji Takayama
 
MT東京03 - Movable Type for AWS
MT東京03 - Movable Type for AWSMT東京03 - Movable Type for AWS
MT東京03 - Movable Type for AWSYuji Takayama
 
Mtとクラウドと私
Mtとクラウドと私Mtとクラウドと私
Mtとクラウドと私Yuji Takayama
 
Movable Type 6 overview spec3
Movable Type 6 overview spec3Movable Type 6 overview spec3
Movable Type 6 overview spec3Yuji Takayama
 
Movable Type 6 Overview - New York Perl Mongers Tech Talk
Movable Type 6 Overview - New York Perl Mongers Tech TalkMovable Type 6 Overview - New York Perl Mongers Tech Talk
Movable Type 6 Overview - New York Perl Mongers Tech TalkYuji Takayama
 
Movable Type 6 Overview SPEC2
Movable Type 6 Overview SPEC2Movable Type 6 Overview SPEC2
Movable Type 6 Overview SPEC2Yuji Takayama
 
Mtddc2013: Movable Type 6 Overview
Mtddc2013: Movable Type 6 OverviewMtddc2013: Movable Type 6 Overview
Mtddc2013: Movable Type 6 OverviewYuji Takayama
 
Mtddc kyusyu-lightningtalks
Mtddc kyusyu-lightningtalksMtddc kyusyu-lightningtalks
Mtddc kyusyu-lightningtalksYuji Takayama
 
Movable Type 5.2 Overview at MTDDC 2012
Movable Type 5.2 Overview at MTDDC 2012Movable Type 5.2 Overview at MTDDC 2012
Movable Type 5.2 Overview at MTDDC 2012Yuji Takayama
 
Phpで作るmovable typeプラグイン
Phpで作るmovable typeプラグインPhpで作るmovable typeプラグイン
Phpで作るmovable typeプラグインYuji Takayama
 
ダイナミック:Plugin
ダイナミック:Pluginダイナミック:Plugin
ダイナミック:PluginYuji Takayama
 

More from Yuji Takayama (17)

Movable Type 7 のすべて
Movable Type 7 のすべてMovable Type 7 のすべて
Movable Type 7 のすべて
 
詳説 Movable type 7
詳説 Movable type 7詳説 Movable type 7
詳説 Movable type 7
 
詳説 Data api mtddc 拡張版 v3対応
詳説 Data api mtddc 拡張版   v3対応詳説 Data api mtddc 拡張版   v3対応
詳説 Data api mtddc 拡張版 v3対応
 
Movable Type for AWS Hands-on
Movable Type for AWS Hands-onMovable Type for AWS Hands-on
Movable Type for AWS Hands-on
 
Data API + AWS = (CMS どうでしょう 札幌編)
Data API + AWS =  (CMS どうでしょう 札幌編)Data API + AWS =  (CMS どうでしょう 札幌編)
Data API + AWS = (CMS どうでしょう 札幌編)
 
Movable Type for AWS - JAWS-UG 沖縄 CMS祭り!
Movable Type for AWS - JAWS-UG 沖縄 CMS祭り!Movable Type for AWS - JAWS-UG 沖縄 CMS祭り!
Movable Type for AWS - JAWS-UG 沖縄 CMS祭り!
 
MT東京03 - Movable Type for AWS
MT東京03 - Movable Type for AWSMT東京03 - Movable Type for AWS
MT東京03 - Movable Type for AWS
 
Mtとクラウドと私
Mtとクラウドと私Mtとクラウドと私
Mtとクラウドと私
 
Movable Type 6 overview spec3
Movable Type 6 overview spec3Movable Type 6 overview spec3
Movable Type 6 overview spec3
 
Movable Type 6 Overview - New York Perl Mongers Tech Talk
Movable Type 6 Overview - New York Perl Mongers Tech TalkMovable Type 6 Overview - New York Perl Mongers Tech Talk
Movable Type 6 Overview - New York Perl Mongers Tech Talk
 
Movable Type 6 Overview SPEC2
Movable Type 6 Overview SPEC2Movable Type 6 Overview SPEC2
Movable Type 6 Overview SPEC2
 
Mtddc2013: Movable Type 6 Overview
Mtddc2013: Movable Type 6 OverviewMtddc2013: Movable Type 6 Overview
Mtddc2013: Movable Type 6 Overview
 
Mtddc kyusyu-lightningtalks
Mtddc kyusyu-lightningtalksMtddc kyusyu-lightningtalks
Mtddc kyusyu-lightningtalks
 
Movable Type 5.2 Overview at MTDDC 2012
Movable Type 5.2 Overview at MTDDC 2012Movable Type 5.2 Overview at MTDDC 2012
Movable Type 5.2 Overview at MTDDC 2012
 
Phpで作るmovable typeプラグイン
Phpで作るmovable typeプラグインPhpで作るmovable typeプラグイン
Phpで作るmovable typeプラグイン
 
ダイナミック:Plugin
ダイナミック:Pluginダイナミック:Plugin
ダイナミック:Plugin
 
20070824 MT-DEVCON
20070824 MT-DEVCON20070824 MT-DEVCON
20070824 MT-DEVCON
 

Data api workshop at Co-Edo

  • 1. Data API 勉強会 Vol.1 2014.6.11 @ Co-Edo YUJI Takayama@Six Apart
  • 2. About Me • 名前: 高山 裕司 • 会社: シックス・アパート • 仕事: Movable Type 全般 • プロダクト・マネージャ • リード・エンジニア github.com/yuji @yuji Yuji Takayama
  • 3. Agenda • Data APIってなに? • 初めての Data API • JavaScript ライブラリ • サインイン 記事の投稿 • こんな使い方も・・・
  • 5. • Movable Type 6 から搭載 • Movable Type に保存されているデー タを操る • REST API • MT のユーザー管理、認証機構を利用
  • 6. • JavaScript のライブラリを提供 • プラグインで API 自体を拡張可能 • 公開サイトでも、管理サイトでも、別の アプリケーションとでも • まだまだ発展途上
  • 8. • 様々なデバイスの登場 • ダイナミック・コンテンツ • MT Perl • ユーザーの役割に応じた画面作り • 管理画面 は、管理する人が使う • コンテンツの作成は、 管理画面 である必要は ない
  • 10. Data API で出来ること Create Read Update Delete Entry ○ ○ ○ ○ Comment ○ ○ ○ ○ Trackback ○ ○ ○ User ○ ○ Site(Blog,Website) ○ Category ○ Site Statistics ○ Asset ○
  • 11. Data API の使い方 http://localhost/mt/mt-data-api.cgi/v1/sites/1 エンドポイント と呼ばれる URL を呼び出す Data API のスクリプトへのパス Data API のバージョン 呼び出すメソッドとパラメータ
  • 13. 呼び出し方で処理が変わる POST GET PUT DELETE Entry ○ ○ ○ ○ Comment ○ ○ ○ ○ Trackback ○ ○ ○ User ○ ○ Site(Blog,Website) ○ Category ○ Site Statistics ○ Asset ○ 同じエンドポイントへのリクエストで変わる
  • 14. 結果は JSON 形式 {! "url" : "http://localhost/blog/20140609-1/",! "archiveUrl" : "http://localhost/blog/20140609-1/",! "name" : "First Website",! "class" : "website",! "id" : "1",! "description" : null! }
  • 18. ユーザー認証 curl -i -d clientId=test -d username=takayama -d password=password http://localhost/cgi-bin/mt/mt-data-api.cgi/v1/authentication -X POST リクエスト 応答 HTTP/1.1 200 OK Date: Mon, 09 Jun 2014 07:01:38 GMT Server: Apache/2.2.26 (Unix) mod_ssl/2.2.26 OpenSSL/1.0.1e DAV/2 PHP/5.3.27 X-content-type: nosniff Cache-control: no-cache Transfer-Encoding: chunked Content-Type: application/json; charset=UTF-8 X-Pad: avoid browser bug ! {"sessionId":"vjqLFlFxEki5ElAHy9DyUe6k3jAuevXJyGdjXk8j","accessToken":"h8YOleAJo aBkNCJl3kmOgmlsocNo0J5LiwZljAV9","expiresIn":3600,"remember":false}
  • 19. 記事の投稿 curl -i http://localhost/cgi-bin/mt/mt-data-api.cgi/v1/sites/1/entries -X POST -H "X-MT-Authorization: MTAuth accessToken=h8YOleAJoaBkNCJl3kmOgmlsocNo0J5LiwZljAV9” -d entry="{"status" : "Publish", "title" : "This is test post", "body" : "Yeah!" }" リクエスト 応答 HTTP/1.1 200 OK Date: Mon, 09 Jun 2014 07:27:00 GMT Server: Apache/2.2.26 (Unix) mod_ssl/2.2.26 OpenSSL/1.0.1e DAV/2 PHP/5.3.27 X-content-type: nosniff Cache-control: no-cache Transfer-Encoding: chunked Content-Type: application/json; charset=UTF-8 X-Pad: avoid browser bug ! {"excerpt":"Yeah!...","date":"2014-06-09T16:27:01u002b09:00","status":"Publish","updatable":true,"author": {"userpicUrl":null,"id":"1","displayName":"Yuji Takayama"},"comments":[],"allowComments":true,"permalink":"http://localhost/blog/ 20140609-1/2014/06/this-is-test-post.html","keywords":"","body":"Yeah!","trackbacks":[],"id": 4,"allowTrackbacks":false,"modifiedDate":"2014-06-09T16:27:01u002b09:00","trackbackCount":0,"blog":{"id":"1"},"categories":[],"tags": [],"commentCount":0,"assets":[],"basename":"this_is_test_post","createdDate":"2014-06-09T16:27:01u002b09:00","class":"entry","title":"This is test post","pingsSentUrl":[],"more":"","customFields":[]}% /Users/takayama% curl - i http://localhost/cgi-bin/mt/mt-data-api.cgi/v1/sites/1/entries -X POST -H "X-MT-Authorization: MTAuth accessToken=h8YOleAJoaBkNCJl3kmOgmlsocNo0J5LiwZljAV9" -d entry="{"status" : "Publish", "title" : "This is test post", "body" : "Yeah!" }"
  • 22. • REST API の呼び出しをラッピング • シンプルな実装なので、他のライブラリ と干渉しにくい • 他の言語系も順次サポート予定
  • 23. 使い方 var  api  =  new  MT.DataAPI({      baseUrl:    "https://your-­‐host/mt/mt-­‐data-­‐api.cgi",      clientId:  "your-­‐client-­‐id"   });   ! api.listEntries(siteId,  function(response)  {      if  (response.error)  {          //  Handle  error          return;      }   !    for  (var  i  =  0;  i  <  response.items.length;  i++)  {              var  entry  =  response.items[i];              //  Render  an  entry      }   }); <script  type=“text/javascript”  src=“http://your-­‐host/path/to/mt-­‐static/ data-­‐api/v1/js/mt-­‐data-­‐api.min.js”></script>
  • 24. var  api  =  new  MT.DataAPI({      baseUrl:    "https://your-­‐host/mt/mt-­‐data-­‐api.cgi",      clientId:  "your-­‐client-­‐id"   });   ! api.getToken(function(response)  {      if  (response.error)  {          if  (response.error.code  ===  401)  {              //  You  have  not  been  authenticated  yet.              location.href  =  api.getAuthorizationUrl(location.href);          }  else  {  /*  Handle  error  */  }      }  else  {          //  You  have  been  authenticated.          api.listEntries(siteId,  {status:  'Draft'},  function(response)  {              if  (response.error)  {  /*  Handle  error  */  return;  }                  //  Fetched  a  list  of  drafts.              for  (var  i  =  0;  i  <  response.items.length;  i++)  {                      var  entry  =  response.items[i];                      //  Render  an  entry              }          });      }   });
  • 27. • Movable Type powered by JavaScript • 記事の投稿に特化した Chrome アプリ • Data API + jQuery + Bootstrap3 • MIT でフォーク自由
  • 28. 使っているメソッド • authenticate(サインイン) • getToken(トークン取得) • listBlogForUser(権限を持っているサイトの一 覧を取得) • createEntry(記事の作成)
  • 29. 初期化    jQuery(document).ready(  function()  {        getSettings().then(              function(settings)  {                  if  (!settings  ||  !settings.apipath)  {                      return  jQuery('#setting-­‐panel-­‐dialog').modal();                  }   !                api  =  new  MT.DataAPI({                      baseUrl:    settings.apipath,                      clientId:  "movabletype-­‐writer"                  });   !                doSignIn(settings.username,  settings.password)                  .then(  loadSiteList  );   .   .   .
  • 30. 初期化    jQuery(document).ready(  function()  {        getSettings().then(              function(settings)  {                  if  (!settings  ||  !settings.apipath)  {                      return  jQuery('#setting-­‐panel-­‐dialog').modal();                  }   !                api  =  new  MT.DataAPI({                      baseUrl:    settings.apipath,                      clientId:  "movabletype-­‐writer"                  });   !                doSignIn(settings.username,  settings.password)                  .then(  loadSiteList  );   .   .   . ローカルストレージから、設定内容を読み込む。 設定されていなければ、設定用のダイアログを表示する
  • 31. 初期化    jQuery(document).ready(  function()  {        getSettings().then(              function(settings)  {                  if  (!settings  ||  !settings.apipath)  {                      return  jQuery('#setting-­‐panel-­‐dialog').modal();                  }   !                api  =  new  MT.DataAPI({                      baseUrl:    settings.apipath,                      clientId:  "movabletype-­‐writer"                  });   !                doSignIn(settings.username,  settings.password)                  .then(  loadSiteList  );   .   .   .Data API のインスタンスを生成する baseUrl には Data API へのURL clientId は任意の文字列
  • 32. 初期化    jQuery(document).ready(  function()  {        getSettings().then(              function(settings)  {                  if  (!settings  ||  !settings.apipath)  {                      return  jQuery('#setting-­‐panel-­‐dialog').modal();                  }   !                api  =  new  MT.DataAPI({                      baseUrl:    settings.apipath,                      clientId:  "movabletype-­‐writer"                  });   !                doSignIn(settings.username,  settings.password)                  .then(  loadSiteList  );   .   .   . ユーザー認証を行う その後、サイト一覧を更新する
  • 33. サインイン    var  doSignIn  =  function(user,  passwd)  {          var  def  =  new  jQuery.Deferred();   !        api.authenticate({  username:  user,  password:  passwd  },                function(response)  {              if  (response.error)  {                  var  code  =  response.error.code;                  var  msg;                  if  (code  ===  404  )  {                  }  else  if  (code  ===  401  )  {                  }  else  {                  }                  return  def.reject(msg);              }  else  {                  api.storeTokenData(response);                  return  def.resolve();              }          });   !        return  def.promise();      };
  • 34. サインイン    var  doSignIn  =  function(user,  passwd)  {          var  def  =  new  jQuery.Deferred();   !        api.authenticate({  username:  user,  password:  passwd  },                function(response)  {              if  (response.error)  {                  var  code  =  response.error.code;                  var  msg;                  if  (code  ===  404  )  {                  }  else  if  (code  ===  401  )  {                  }  else  {                  }                  return  def.reject(msg);              }  else  {                  api.storeTokenData(response);                  return  def.resolve();              }          });   !        return  def.promise();      }; 認証用のエンドポイントを呼び出す。 認証エラーは、response.error の有無で判定 認証に成功したら、storeTokenData でセッションデータを保存
  • 35. サイト一覧の取得    var  loadSiteList  =  function()  {          var  def  =  new  jQuery.Deferred();   !        api.listBlogsForUser('me',  function(response)  {              if  (response.error)  {                  var  code  =  response.error.code;                  var  msg;                  if  (code  ===  404  )  {                  }  else  if  (code  ===  403  )  {                  }  else  {                  }                  return  def.reject(msg);              }   !            var  $blogListBox  =  jQuery('#form-­‐blog-­‐list');              response.items.forEach(  function(x,  i)  {                  $blogListBox.append($('<option>').html(x.name).val(x.id));              });              $blogListBox.removeAttr('disabled');          });  
  • 36. サイト一覧の取得    var  loadSiteList  =  function()  {          var  def  =  new  jQuery.Deferred();   !        api.listBlogsForUser('me',  function(response)  {              if  (response.error)  {                  var  code  =  response.error.code;                  var  msg;                  if  (code  ===  404  )  {                  }  else  if  (code  ===  403  )  {                  }  else  {                  }                  return  def.reject(msg);              }   !            var  $blogListBox  =  jQuery('#form-­‐blog-­‐list');              response.items.forEach(  function(x,  i)  {                  $blogListBox.append($('<option>').html(x.name).val(x.id));              });              $blogListBox.removeAttr('disabled');          });   ユーザーが権限を持つサイトの一覧を取得する エラー 404: サイトが見つからない エラー: 403: 認証エラー
  • 37. サイト一覧の取得    var  loadSiteList  =  function()  {          var  def  =  new  jQuery.Deferred();   !        api.listBlogsForUser('me',  function(response)  {              if  (response.error)  {                  var  code  =  response.error.code;                  var  msg;                  if  (code  ===  404  )  {                  }  else  if  (code  ===  403  )  {                  }  else  {                  }                  return  def.reject(msg);              }   !            var  $blogListBox  =  jQuery('#form-­‐blog-­‐list');              response.items.forEach(  function(x,  i)  {                  $blogListBox.append($('<option>').html(x.name).val(x.id));              });              $blogListBox.removeAttr('disabled');          });   セレクトボックスに読み込んだサイトの一覧を追加
  • 38. 記事の投稿    jQuery('#button-­‐post').click(  function()  {          var  entry  =  {};          entry['title']  =  jQuery('#entry-­‐title').val();          entry['body']  =  jQuery('#entry-­‐body').code();          entry['status']  =  'Publish';          var  siteId  =  jQuery('#form-­‐blog-­‐list  option:selected').val();          api.getToken(function(response)  {              if  (response.error)  {  }              api.createEntry(siteId,  entry,  function(response)  {                  if  (response.error)  {                      var  code  =  response.error.code;                      var  msg;                      if  (code  ===  404  )  {                  }  else  if  (code  ===  401  )  {                      }  else  if  (code  ===  403  )  {                      }  else  {                      }                  }              }          }      }
  • 39. 記事の投稿    jQuery('#button-­‐post').click(  function()  {          var  entry  =  {};          entry['title']  =  jQuery('#entry-­‐title').val();          entry['body']  =  jQuery('#entry-­‐body').code();          entry['status']  =  'Publish';          var  siteId  =  jQuery('#form-­‐blog-­‐list  option:selected').val();          api.getToken(function(response)  {              if  (response.error)  {  }              api.createEntry(siteId,  entry,  function(response)  {                  if  (response.error)  {                      var  code  =  response.error.code;                      var  msg;                      if  (code  ===  404  )  {                  }  else  if  (code  ===  401  )  {                      }  else  if  (code  ===  403  )  {                      }  else  {                      }                  }              }          }      } エントリーデータをハッシュで作成
  • 40. 記事の投稿    jQuery('#button-­‐post').click(  function()  {          var  entry  =  {};          entry['title']  =  jQuery('#entry-­‐title').val();          entry['body']  =  jQuery('#entry-­‐body').code();          entry['status']  =  'Publish';          var  siteId  =  jQuery('#form-­‐blog-­‐list  option:selected').val();          api.getToken(function(response)  {              if  (response.error)  {  }              api.createEntry(siteId,  entry,  function(response)  {                  if  (response.error)  {                      var  code  =  response.error.code;                      var  msg;                      if  (code  ===  404  )  {                  }  else  if  (code  ===  401  )  {                      }  else  if  (code  ===  403  )  {                      }  else  {                      }                  }              }          }      } トークンの有効期限が過ぎている場合は、再取得が必要
  • 41. 記事の投稿    jQuery('#button-­‐post').click(  function()  {          var  entry  =  {};          entry['title']  =  jQuery('#entry-­‐title').val();          entry['body']  =  jQuery('#entry-­‐body').code();;          entry['status']  =  'Publish';          var  siteId  =  jQuery('#form-­‐blog-­‐list  option:selected').val();          api.getToken(function(response)  {              if  (response.error)  {  }              api.createEntry(siteId,  entry,  function(response)  {                  if  (response.error)  {                      var  code  =  response.error.code;                      var  msg;                      if  (code  ===  404  )  {                  }  else  if  (code  ===  401  )  {                      }  else  if  (code  ===  403  )  {                      }  else  {                      }                  }              }          }      } エントリの作成をおこなう エラー 404: 投稿先のサイトが見つからない エラー 403: 権限がない エラー 401: 認証エラー
  • 45. API の呼び出しは非同期 初期化パラメータで同期にすることも可能 ! var api = new MT.DataAPI({ clientId: your-client-id , baseUrl: https://your-host/your-mt-api.cgi', async: false });
  • 46. 認証URL vs 認証呼び出し ブラウザからの利用であれば、authenticate ではなく、 getAuthorizationUrl を使って MT 標準のサインイン画 面を利用する方がいい(セキュリティ、信頼性) ! var url = api.getAuthorizationUrl( https://your-host/your-app/ ) // リダイレクト先 );
  • 47. クロスドメイン クロスドメイン間の通信は原則禁止されているので、 適宜 環境変数を設定する ! 少なくとも DataAPICORSAllowOrigin * DataAPICORSAllowOrigin http://www.example.com, http://beta.example.com ! ついでに DataAPICORSAllowHeaders DataAPICORSExposeHeaders DataAPICORSAllowMethods など
  • 53. Google Analytics • MTにGoogle Analyticsの設定があれば • Data API から Google Analyticsのデー タを読み込める
  • 54. Chrome • タグ・環境変数の検索 by Omnibox • 再構築の定期実行 by Alarm • スニペット挿入 by BrowserAction • 詳しくは、この後のお話で!
  • 56. • 色々まだ足りてないですよね? • 次以降のリリースで含まれる Data API の機能をプラグインで随時リリース予定 • 震えて、待て!