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) ○
Cate...
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 ○
Si...
結果は JSON 形式
{!
"url" : "http://localhost/blog/20140609-1/",!
"archiveUrl" : "http://localhost/blog/20140609-1/",!
"name" :...
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/...
記事の投稿
curl -i http://localhost/cgi-bin/mt/mt-data-api.cgi/v1/sites/1/entries -X POST	
-H "X-MT-Authorization: MTAuth acces...
まぁ、無理ですよね
(́・ω・`)
JavaScript
ライブラリ
• REST API の呼び出しをラッピング
• シンプルな実装なので、他のライブラリ
と干渉しにくい
• 他の言語系も順次サポート予定
使い方
var  api  =  new  MT.DataAPI({  
    baseUrl:    "https://your-­‐host/mt/mt-­‐data-­‐api.cgi",  
    clientId:  "your-...
var  api  =  new  MT.DataAPI({  
    baseUrl:    "https://your-­‐host/mt/mt-­‐data-­‐api.cgi",  
    clientId:  "your-­‐cl...
サインイン から
記事のポストまで
実
践
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)  {  
         ...
初期化
    jQuery(document).ready(  function()  {  
      getSettings().then(  
            function(settings)  {  
         ...
初期化
    jQuery(document).ready(  function()  {  
      getSettings().then(  
            function(settings)  {  
         ...
初期化
    jQuery(document).ready(  function()  {  
      getSettings().then(  
            function(settings)  {  
         ...
サインイン
    var  doSignIn  =  function(user,  passwd)  {  
        var  def  =  new  jQuery.Deferred();  
!
        api.auth...
サインイン
    var  doSignIn  =  function(user,  passwd)  {  
        var  def  =  new  jQuery.Deferred();  
!
        api.auth...
サイト一覧の取得
    var  loadSiteList  =  function()  {  
        var  def  =  new  jQuery.Deferred();  
!
        api.listBlogsF...
サイト一覧の取得
    var  loadSiteList  =  function()  {  
        var  def  =  new  jQuery.Deferred();  
!
        api.listBlogsF...
サイト一覧の取得
    var  loadSiteList  =  function()  {  
        var  def  =  new  jQuery.Deferred();  
!
        api.listBlogsF...
記事の投稿
    jQuery('#button-­‐post').click(  function()  {  
        var  entry  =  {};  
        entry['title']  =  jQuery(...
記事の投稿
    jQuery('#button-­‐post').click(  function()  {  
        var  entry  =  {};  
        entry['title']  =  jQuery(...
記事の投稿
    jQuery('#button-­‐post').click(  function()  {  
        var  entry  =  {};  
        entry['title']  =  jQuery(...
記事の投稿
    jQuery('#button-­‐post').click(  function()  {  
        var  entry  =  {};  
        entry['title']  =  jQuery(...
ユーザー専用
投稿ツール
タイトル
カスタムフィールド
カスタムフィールド
本文
JavaScript
ライブラリ
勘所
API の呼び出しは非同期
初期化パラメータで同期にすることも可能
!
var api = new MT.DataAPI({
clientId: your-client-id ,
baseUrl: https://your-host/your-...
認証URL vs 認証呼び出し
ブラウザからの利用であれば、authenticate ではなく、
getAuthorizationUrl を使って MT 標準のサインイン画
面を利用する方がいい(セキュリティ、信頼性)
!
var url = ...
クロスドメイン
クロスドメイン間の通信は原則禁止されているので、
適宜 環境変数を設定する
!
少なくとも
DataAPICORSAllowOrigin *
DataAPICORSAllowOrigin http://www.example.c...
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
の機能をプラグインで随時リリース予定
• 震えて、待て!
Upcoming SlideShare
Loading in …5
×

Data api workshop at Co-Edo

4,217 views

Published on

Published in: Engineering
0 Comments
3 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
4,217
On SlideShare
0
From Embeds
0
Number of Embeds
1,119
Actions
Shares
0
Downloads
2
Comments
0
Likes
3
Embeds 0
No embeds

No notes for slide

Data api workshop at Co-Edo

  1. 1. Data API 勉強会 Vol.1 2014.6.11 @ Co-Edo YUJI Takayama@Six Apart
  2. 2. About Me • 名前: 高山 裕司 • 会社: シックス・アパート • 仕事: Movable Type 全般 • プロダクト・マネージャ • リード・エンジニア github.com/yuji @yuji Yuji Takayama
  3. 3. Agenda • Data APIってなに? • 初めての Data API • JavaScript ライブラリ • サインイン 記事の投稿 • こんな使い方も・・・
  4. 4. Data APIって何?
  5. 5. • Movable Type 6 から搭載 • Movable Type に保存されているデー タを操る • REST API • MT のユーザー管理、認証機構を利用
  6. 6. • JavaScript のライブラリを提供 • プラグインで API 自体を拡張可能 • 公開サイトでも、管理サイトでも、別の アプリケーションとでも • まだまだ発展途上
  7. 7. なぜ、Data API を リリースしたのか
  8. 8. • 様々なデバイスの登場 • ダイナミック・コンテンツ • MT Perl • ユーザーの役割に応じた画面作り • 管理画面 は、管理する人が使う • コンテンツの作成は、 管理画面 である必要は ない
  9. 9. 初めての Data API
  10. 10. Data API で出来ること Create Read Update Delete Entry ○ ○ ○ ○ Comment ○ ○ ○ ○ Trackback ○ ○ ○ User ○ ○ Site(Blog,Website) ○ Category ○ Site Statistics ○ Asset ○
  11. 11. Data API の使い方 http://localhost/mt/mt-data-api.cgi/v1/sites/1 エンドポイント と呼ばれる URL を呼び出す Data API のスクリプトへのパス Data API のバージョン 呼び出すメソッドとパラメータ
  12. 12. https://github.com/movabletype/Documentation/wiki/Quick-reference
  13. 13. 呼び出し方で処理が変わる POST GET PUT DELETE Entry ○ ○ ○ ○ Comment ○ ○ ○ ○ Trackback ○ ○ ○ User ○ ○ Site(Blog,Website) ○ Category ○ Site Statistics ○ Asset ○ 同じエンドポイントへのリクエストで変わる
  14. 14. 結果は JSON 形式 {! "url" : "http://localhost/blog/20140609-1/",! "archiveUrl" : "http://localhost/blog/20140609-1/",! "name" : "First Website",! "class" : "website",! "id" : "1",! "description" : null! }
  15. 15. https://github.com/movabletype/Documentation/wiki/Quick-reference
  16. 16. • HTTP(s) を呼び出せれば呼び出し元は ブラウザだろうが、アプリだろうが、コ ンソールだろうが、何でもいい • 戻りは JSON 形式なので、JSON パー サがある方がラクと言えばラク
  17. 17. サインイン から 記事のポストまで 実 践
  18. 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. 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!" }"
  20. 20. まぁ、無理ですよね (́・ω・`)
  21. 21. JavaScript ライブラリ
  22. 22. • REST API の呼び出しをラッピング • シンプルな実装なので、他のライブラリ と干渉しにくい • 他の言語系も順次サポート予定
  23. 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. 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              }          });      }   });
  25. 25. サインイン から 記事のポストまで 実 践
  26. 26. MovableType Writer(仮) https://github.com/movabletype/MovableTypeWriter
  27. 27. • Movable Type powered by JavaScript • 記事の投稿に特化した Chrome アプリ • Data API + jQuery + Bootstrap3 • MIT でフォーク自由
  28. 28. 使っているメソッド • authenticate(サインイン) • getToken(トークン取得) • listBlogForUser(権限を持っているサイトの一 覧を取得) • createEntry(記事の作成)
  29. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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. 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: 認証エラー
  42. 42. ユーザー専用 投稿ツール
  43. 43. タイトル カスタムフィールド カスタムフィールド 本文
  44. 44. JavaScript ライブラリ 勘所
  45. 45. API の呼び出しは非同期 初期化パラメータで同期にすることも可能 ! var api = new MT.DataAPI({ clientId: your-client-id , baseUrl: https://your-host/your-mt-api.cgi', async: false });
  46. 46. 認証URL vs 認証呼び出し ブラウザからの利用であれば、authenticate ではなく、 getAuthorizationUrl を使って MT 標準のサインイン画 面を利用する方がいい(セキュリティ、信頼性) ! var url = api.getAuthorizationUrl( https://your-host/your-app/ ) // リダイレクト先 );
  47. 47. クロスドメイン クロスドメイン間の通信は原則禁止されているので、 適宜 環境変数を設定する ! 少なくとも DataAPICORSAllowOrigin * DataAPICORSAllowOrigin http://www.example.com, http://beta.example.com ! ついでに DataAPICORSAllowHeaders DataAPICORSExposeHeaders DataAPICORSAllowMethods など
  48. 48. Data API こんな使い方も
  49. 49. スマートフォンアプリ • スマフォサイトをウェブアプリとして • ネイティブアプリから利用して • Movable Type as Backend Service
  50. 50. Ajax 検索 • インクリメンタルサーチ • MT-Search.cgi よりも軽量
  51. 51. ページネーション • 画面のスクロールでインクリメンタルな 読み込み • 検索結果などページネーション
  52. 52. 社内システムなど • 社内ポータルに、記事作成のインターフェ イスを用意して、簡単に記事をポスト • 一般ユーザーは、MTの画面を見る必要 がない
  53. 53. Google Analytics • MTにGoogle Analyticsの設定があれば • Data API から Google Analyticsのデー タを読み込める
  54. 54. Chrome • タグ・環境変数の検索 by Omnibox • 再構築の定期実行 by Alarm • スニペット挿入 by BrowserAction • 詳しくは、この後のお話で!
  55. 55. Next Data API…
  56. 56. • 色々まだ足りてないですよね? • 次以降のリリースで含まれる Data API の機能をプラグインで随時リリース予定 • 震えて、待て!

×