溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

如何創(chuàng)建以API為中心的Web應(yīng)用

發(fā)布時(shí)間:2021-10-29 17:28:12 來(lái)源:億速云 閱讀:200 作者:柒染 欄目:編程語(yǔ)言

如何創(chuàng)建以API為中心的Web應(yīng)用,針對(duì)這個(gè)問(wèn)題,這篇文章詳細(xì)介紹了相對(duì)應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問(wèn)題的小伙伴找到更簡(jiǎn)單易行的方法。

正計(jì)劃著要開(kāi)始搞一個(gè)新的網(wǎng)絡(luò)應(yīng)用?在這篇教程中,我們將討論如何創(chuàng)建以API為中心的網(wǎng)絡(luò)應(yīng)用,還會(huì)解釋在今天的多平臺(tái)世界,這類(lèi)應(yīng)用為什么是重要的。

引言

API?

對(duì)于還不甚熟悉這個(gè)術(shù)語(yǔ)的朋友,API是Application Programming Interface(應(yīng)用編程接口)的簡(jiǎn)稱(chēng)。根據(jù)維基百科:

 API是以源代碼為基礎(chǔ)的約定,它用于軟件組件之間相互通信的接口。API可能包含函數(shù)、數(shù)據(jù)結(jié)構(gòu)、對(duì)象類(lèi)、以及變量等的約定。

如何創(chuàng)建以API為中心的Web應(yīng)用

API可視化

圖片蒙惠http://blog.zoho.com

簡(jiǎn)單地講,API指的是一組應(yīng)用中的函數(shù),它們能夠被其它應(yīng)用(或者這些函數(shù)所屬應(yīng)用自己,下文中我們將會(huì)看到)用來(lái)與應(yīng)用進(jìn)行交互。API是一種很棒的向外部應(yīng)用安全和妥善地表明其功能的方式,因?yàn)檫@些外部應(yīng)用所能利用的所有功能僅限于API中所表現(xiàn)出的功能。

什么是“以API為中心的”網(wǎng)絡(luò)應(yīng)用?

 以API為中心的網(wǎng)絡(luò)應(yīng)用就是基本上通過(guò)API調(diào)用執(zhí)行大多數(shù)甚或所有功能的一類(lèi)網(wǎng)絡(luò)應(yīng)用。

以API為中心的網(wǎng)絡(luò)應(yīng)用就是基本上通過(guò)API調(diào)用執(zhí)行大多數(shù)甚或所有功能的一類(lèi)網(wǎng)絡(luò)應(yīng)用。舉個(gè)例子,如果你正要登錄一個(gè)用戶(hù),你應(yīng)當(dāng)將其認(rèn)證信息發(fā)送給API,然后API會(huì)向你返回一個(gè)結(jié)果,說(shuō)明該用戶(hù)是否提供了正確的用戶(hù)名-密碼組合。

以API為中心的網(wǎng)絡(luò)應(yīng)用的另外一個(gè)特征就是API一直是無(wú)狀態(tài)的,這意味著這種應(yīng)用無(wú)法辨別由會(huì)話(huà)發(fā)起的API調(diào)用。由于API調(diào)用通常由后端代碼構(gòu)成,實(shí)現(xiàn)對(duì)會(huì)話(huà)的掌控將比較困難,因?yàn)檫@其中通常沒(méi)有cookies介入。這種局限事實(shí)上是好事——它“迫使”開(kāi)發(fā)者建造不基于當(dāng)前用戶(hù)狀態(tài)工作的 API,但是相應(yīng)地在功能上,它使測(cè)試易于進(jìn)行,因?yàn)橛脩?hù)的當(dāng)前狀態(tài)無(wú)需被重建。

為什么要經(jīng)歷這些麻煩?

作為Web開(kāi)發(fā)者,我們已經(jīng)親眼目睹了技術(shù)的進(jìn)步。有一個(gè)常識(shí)是,當(dāng)代的人們不會(huì)只通過(guò)瀏覽器來(lái)使用應(yīng)用,還會(huì)通過(guò)其它諸如移動(dòng)電話(huà)和平板電腦之類(lèi)的設(shè)備使用。舉個(gè)例子,這篇發(fā)表在Mashable上的名為“用戶(hù)在移動(dòng)應(yīng)用上花的時(shí)間比在網(wǎng)絡(luò)上的多”的寫(xiě)道:

 一項(xiàng)新近的報(bào)告表明,用戶(hù)花在移動(dòng)應(yīng)用上的時(shí)間首次超過(guò)了花在網(wǎng)絡(luò)上的時(shí)間。

 

 Flurry對(duì)比了其移動(dòng)數(shù)據(jù)與來(lái)自comScore和Alexa的統(tǒng)計(jì)數(shù)據(jù),發(fā)現(xiàn)在六月,用戶(hù)每天花費(fèi)81分鐘使用移動(dòng)應(yīng)用,而只花74分鐘用于網(wǎng)上沖浪。

這里還有一篇來(lái)自ReadWriteWeb的更新的文章“在移動(dòng)設(shè)備上瀏覽網(wǎng)絡(luò)的人多于使用IE6和IE7的人數(shù)總和”:

 來(lái)自Sitepoint的 瀏覽器趨勢(shì)的最新數(shù)據(jù)表明,在智能手機(jī)上瀏覽Web的人比使用IE6和IE7瀏覽的人更多。這兩件難有起色的老古董多年來(lái)一直是Web開(kāi)發(fā)者的噩夢(mèng),它們需要各網(wǎng)站盡可能妥當(dāng)?shù)亟蹈竦街辽俪S脼g覽器所能支持的水平。但是現(xiàn)在時(shí)代不同了;2011年十一月中,6.95%的Web活動(dòng)在移動(dòng)瀏覽器上發(fā)生,而發(fā)生在IE6或 IE7上的則只有6.49%。

正如我們所見(jiàn),越來(lái)越多的人正通過(guò)其它途徑獲得訊息,特別是移動(dòng)設(shè)備。

這與我創(chuàng)建以API為中心的網(wǎng)絡(luò)應(yīng)用有何關(guān)系?

 這必將會(huì)使我們的應(yīng)用更加有用,因?yàn)樗梢杂迷谌魏文阈枰牡胤健?

創(chuàng)建以API為中心的網(wǎng)絡(luò)應(yīng)用的主要優(yōu)勢(shì)之一便是它幫助你建立可以用于任何設(shè)備的功能,瀏覽器、移動(dòng)電話(huà)、甚至是桌面應(yīng)用。你所需要做的就是創(chuàng)建的API 能夠使所有這些設(shè)備利用它完成通信,然后,瞧!你將能夠建造一個(gè)集中式應(yīng)用,它能夠接受來(lái)自用戶(hù)所使用的任何設(shè)備的輸入并執(zhí)行相應(yīng)的功能。

如何創(chuàng)建以API為中心的Web應(yīng)用

以API為中心的應(yīng)用的框圖

通過(guò)以這種方式創(chuàng)建應(yīng)用,我們能夠從容地利用不同的人使用不同的媒介這一優(yōu)勢(shì)。這必將使應(yīng)用更加有用,因?yàn)樗苡迷谟脩?hù)需要的任何地方。

為了證明我們的觀點(diǎn),這里有一篇關(guān)于Twitter的重新設(shè)計(jì)的網(wǎng)站的文章,文章告訴我們他們現(xiàn)在如何利用他們的API來(lái)驅(qū)動(dòng)Twitter.com的,實(shí)質(zhì)上是使其以API為中心:

 最重要的架構(gòu)改動(dòng)之一就是Twitter.com現(xiàn)在是我們自己API的客戶(hù)。它從終端提取數(shù)據(jù),此終端與移動(dòng)網(wǎng)站,我們?yōu)閕Phone、iPad、 Android,以及所有第三方應(yīng)用所用端點(diǎn)相同。這一轉(zhuǎn)變使我們能向API團(tuán)隊(duì)分配更多的資源,同時(shí)生成了40多個(gè)補(bǔ)丁。在初始頁(yè)面負(fù)載和來(lái)自客戶(hù)端的每個(gè)調(diào)用上,所有的數(shù)據(jù)現(xiàn)在都是從一個(gè)高度優(yōu)化的JSON段緩存中獲取的。

在本篇教程中,我們將創(chuàng)建一個(gè)簡(jiǎn)單的TODO列表應(yīng)用,該應(yīng)用以API為中心;還要?jiǎng)?chuàng)建一個(gè)瀏覽器上的前端客戶(hù)端,該客戶(hù)端與我們的TODO列表應(yīng)用進(jìn)行交互。文末,你就能了解一個(gè)以API為中心的應(yīng)用的有機(jī)組成部分,同時(shí),還能了解怎樣使應(yīng)用和客戶(hù)端兩者之間的安全通信變得容易。記住這些,我們開(kāi)始吧!

步驟 1: 規(guī)劃該應(yīng)用的功能

本教程中我們將要構(gòu)建的這個(gè) TODO 應(yīng)用將會(huì)有下面幾個(gè)基本的CRUD功能:

  • 創(chuàng)建 TODO 條目

  • 讀取 TODO 條目

  • 更新 TODO 條目 (重命名,標(biāo)記為完成,標(biāo)記為未完成)

  • 刪除 TODO 條目

每一個(gè) TODO 條目將擁有:

  • 一個(gè)標(biāo)題 Title

  • 一個(gè)截止日期 Date Due

  • 一個(gè)描述 Description

  • 一個(gè)判斷 TODO 條目是否完成的標(biāo)志 Is Done

讓我們模擬一下該應(yīng)用,使我們考慮該應(yīng)用以后會(huì)是什么樣子時(shí),能有有一個(gè)直觀的參考:

如何創(chuàng)建以API為中心的Web應(yīng)用 
簡(jiǎn)單的TODO 模擬示例

步驟 2: 創(chuàng)建API服務(wù)器

既然我們是在開(kāi)發(fā)一個(gè)以API為中心的應(yīng)用,我們將創(chuàng)建兩個(gè)“項(xiàng)目”: API 服務(wù)器,和前端客戶(hù)端。 我們首先從創(chuàng)建API服務(wù)器開(kāi)始。

在你的web server文件夾,創(chuàng)建一個(gè)文件夾,命名為simpletodo_api,然后創(chuàng)建一個(gè)index.php文件。這個(gè)index.php文件將作為一個(gè)訪(fǎng)問(wèn)API的前端控制器,所以,所有訪(fǎng)問(wèn)API服務(wù)器的請(qǐng)求都會(huì)由該文件產(chǎn)生。打開(kāi)它并往里輸入下列代碼:

<?php  // 定義數(shù)據(jù)目錄的路徑  define('DATA_PATH', realpath(dirname(__FILE__).'/data'));   //引入我們的models  include_once 'models/TodoItem.php';   //在一個(gè)try-catch塊中包含所有代碼,來(lái)捕獲所有可能的異常!  try {      //獲得在POST/GET request中的所有參數(shù)      $params = $_REQUEST;            //獲取controller并把它正確的格式化使得第一個(gè)字母總是大寫(xiě)的      $controller = ucfirst(strtolower($params['controller']));            //獲取action并把它正確的格式化,使它所有的字母都是小寫(xiě)的,并追加一個(gè)'Action'      $action = strtolower($params['action']).'Action';       //檢查controller是否存在。如果不存在,拋出異常      if( file_exists("controllers/{$controller}.php") ) {          include_once "controllers/{$controller}.php";      } else {          throw new Exception('Controller is invalid.');      }            //創(chuàng)建一個(gè)新的controller實(shí)例,并把從request中獲取的參數(shù)傳給它      $controller = new $controller($params);            //檢查controller中是否存在action。如果不存在,拋出異常。      if( method_exists($controller, $action) === false ) {          throw new Exception('Action is invalid.');      }            //執(zhí)行action      $result['data'] = $controller->$action();      $result['success'] = true;        } catch( Exception $e ) {      //捕獲任何一次樣并且報(bào)告問(wèn)題      $result = array();      $result['success'] = false;      $result['errormsg'] = $e->getMessage();  }   //回顯調(diào)用API的結(jié)果  echo json_encode($result);  exit();

實(shí)質(zhì)上,這里我們創(chuàng)建的是一個(gè)簡(jiǎn)單的前端控制器,它實(shí)現(xiàn)了下列功能:

  • 接受一次擁有任意個(gè)參數(shù)的API調(diào)用

  • 為本次API調(diào)用抽取出Controller和Action

  • 進(jìn)行必要的檢查確保Controller和Action都存在

  • 執(zhí)行API調(diào)用

  • 捕獲異常,如果有的話(huà)

  • 返回一個(gè)結(jié)果給調(diào)用者

除了需要?jiǎng)?chuàng)建index.php外你還需要?jiǎng)?chuàng)建三個(gè)文件夾:  controllers, models 和  data.

如何創(chuàng)建以API為中心的Web應(yīng)用

  • controllers  文件夾存放的是所有我們API服務(wù)器將會(huì)用到的的控制器。我們用MVC架構(gòu)來(lái)使API服務(wù)器結(jié)構(gòu)更清楚合理。

  • models 文件夾存放所有API服務(wù)器要用到的數(shù)據(jù)模型。

  • data 文件夾將會(huì)用來(lái)保存API服務(wù)器的任何數(shù)據(jù)。

在controllers文件夾下創(chuàng)建一個(gè)叫Todo.php的文件。這將是任何TODO列表有關(guān)任務(wù)的控制器。按照TODO應(yīng)用所需提供的功能,向Todo控制器里面添加必要的方法:

<?php  class Todo  {      private $_params;            public function __construct($params)      {          $this->_params = $params;      }            public function createAction()      {          //create a new todo item      }            public function readAction()      {          //read all the todo items      }            public function updateAction()      {          //update a todo item      }            public function deleteAction()      {          //delete a todo item      }  }

現(xiàn)在為每個(gè)action中添加必要的功能實(shí)現(xiàn)。我將會(huì)提供createAction()方法的源碼,其他方法將留作作業(yè)。如果你覺(jué)得毫無(wú)頭緒,你也可以下載示例的源碼,從那里拷貝。

public function createAction()  {      //create a new todo item      $todo = new TodoItem();      $todo->title = $this->_params['title'];      $todo->description = $this->_params['description'];      $todo->due_date = $this->_params['due_date'];      $todo->is_done = 'false';            //pass the user's username and password to authenticate the user      $todo->save($this->_params['username'], $this->_params['userpass']);            //return the todo item in array format      return $todo->toArray();  }

在文件夾models下創(chuàng)建TodoItem.php,這樣我們就可以創(chuàng)建“條目添加”的代碼了。注意:我并沒(méi)有和數(shù)據(jù)庫(kù)進(jìn)行連接,相反我將信息保存到文件中,雖然這可以用任何數(shù)據(jù)庫(kù)來(lái)實(shí)現(xiàn),但是 這樣做相對(duì)來(lái)說(shuō)要容易些。

<?php  class TodoItem  {      public $todo_id;      public $title;      public $description;      public $due_date;      public $is_done;            public function save($username, $userpass)      {          //get the username/password hash          $userhash = sha1("{$username}_{$userpass}");          if( is_dir(DATA_PATH."/{$userhash}") === false ) {              mkdir(DATA_PATH."/{$userhash}");          }                    //if the $todo_id isn't set yet, it means we need to create a new todo item          if( is_null($this->todo_id) || !is_numeric($this->todo_id) ) {              //the todo id is the current time              $this->todo_id = time();          }                    //get the array version of this todo item          $todo_item_array = $this->toArray();                    //save the serialized array version into a file          $success = file_put_contents(DATA_PATH."/{$userhash}/{$this->todo_id}.txt", serialize($todo_item_array));                    //if saving was not successful, throw an exception          if( $success === false ) {              throw new Exception('Failed to save todo item');          }                    //return the array version          return $todo_item_array;      }            public function toArray()      {          //return an array version of the todo item          return array(              'todo_id' => $this->todo_id,              'title' => $this->title,              'description' => $this->description,              'due_date' => $this->due_date,              'is_done' => $this->is_done          );      }  }

createAction方法使用到TodoItem模型里面兩個(gè)方法:

  • save() &ndash; 該方法將TodoItem保存到一個(gè)文件中,如有必要,需要設(shè)置todo_id。

  • toArray() &ndash; 該方法返回一個(gè)以變量為索引的數(shù)組Todo條目。

由于API需要通過(guò)HTTP請(qǐng)求調(diào)用,在瀏覽器輸入如下地址測(cè)試API:

http://localhost/simpletodo_api/?controller=todo&action=create&title=test%20title&description=test%20description&due_date=12/08/2011&username=nikko&userpass=test1234

如果沒(méi)有錯(cuò),你應(yīng)該在data文件夾下看到一個(gè)新的文件夾,在該文件夾里面有一個(gè)文件,文件內(nèi)容如下:

如何創(chuàng)建以API為中心的Web應(yīng)用 

createAction()結(jié)果

恭喜!您已經(jīng)成功創(chuàng)建了一個(gè)的API服務(wù)器和API調(diào)用!

步驟3:確保API服務(wù)器具有APP ID和APP SECRET

目前,API服務(wù)器被設(shè)置為接受全部API請(qǐng)求。我們將需要將之限制在我們自己的應(yīng)用上,以確保只有我們自己的前端客戶(hù)端能夠完成API請(qǐng)求。另外,你實(shí)際上也可以創(chuàng)建一個(gè)系統(tǒng),其中的用戶(hù)可以創(chuàng)建他們自己的應(yīng)用,而那些應(yīng)用也用用對(duì)你的API服務(wù)器的訪(fǎng)問(wèn)權(quán),這與Facebook和Twitter的應(yīng)用的的工作原理類(lèi)似。

我們從為使用API服務(wù)器的用戶(hù)創(chuàng)建一組id-密碼對(duì)開(kāi)始。由于這只是一個(gè)Demo,我們可以使用任何隨機(jī)的、32位字符串。對(duì)于APP ID,我們將其設(shè)定為APP001

再次打開(kāi)index.php文件,然后用下列代碼更新之:

<?php  // Define path to data folder  define('DATA_PATH', realpath(dirname(__FILE__).'/data'));   //Define our id-key pairs  $applications = array(      'APP001' => '28e336ac6c9423d946ba02d19c6a2632', //randomly generated app key   );  //include our models  include_once 'models/TodoItem.php';   //wrap the whole thing in a try-catch block to catch any wayward exceptions!  try {      //*UPDATED*      //get the encrypted request      $enc_request = $_REQUEST['enc_request'];            //get the provided app id      $app_id = $_REQUEST['app_id'];            //check first if the app id exists in the list of applications      if( !isset($applications[$app_id]) ) {          throw new Exception('Application does not exist!');      }            //decrypt the request      $params = json_decode(trim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, $applications[$app_id], base64_decode($enc_request), MCRYPT_MODE_ECB)));            //check if the request is valid by checking if it's an array and looking for the controller and action      if( $params == false || isset($params->controller) == false || isset($params->action) == false ) {          throw new Exception('Request is not valid');      }            //cast it into an array      $params = (array) $params;      ...      ...      ...

我們?cè)谶@里已經(jīng)完成的實(shí)際上是實(shí)現(xiàn)一個(gè)非常簡(jiǎn)單的認(rèn)證我們的前端客戶(hù)端的方法,它利用了與公共-私有密鑰認(rèn)證相似的系統(tǒng)。基本上,這里給出的就是認(rèn)證過(guò)程的步驟分解:

如何創(chuàng)建以API為中心的Web應(yīng)用 
公鑰加密

  • 完成一個(gè)API調(diào)用,其中提供了$app_id$enc_request

  • $enc_request的值是API調(diào)用的參數(shù),利用APP KEY進(jìn)行加密。APP KEY絕對(duì)不會(huì)被發(fā)送到服務(wù)器,它只是被用來(lái)散列請(qǐng)求。此外,該請(qǐng)求只能利用APP KEY被解密

  • 一旦API調(diào)用到達(dá)API服務(wù)器,它會(huì)查驗(yàn)它自己的應(yīng)用列表是否與APP ID所提供的一致

  • 當(dāng)調(diào)用被發(fā)現(xiàn),API服務(wù)器嘗試?yán)门cAPP ID發(fā)送的密鑰相匹配的密鑰進(jìn)行解密

  • 如果請(qǐng)求被解密成功,那么繼續(xù)執(zhí)行程序

既然API服務(wù)器已經(jīng)確保具有APP ID和APP SECRET,那么我們就可以開(kāi)始編寫(xiě)使用API服務(wù)器的前端客戶(hù)端了。

步驟4:創(chuàng)建瀏覽器客戶(hù)端

我們從為前端客戶(hù)端設(shè)定新建文件夾開(kāi)始。在你的Web服務(wù)器上的文件夾中創(chuàng)建一個(gè)名為simpletodo_client_browser的文件夾。完成后,創(chuàng)建一個(gè)index.php文件,并將下列代碼寫(xiě)進(jìn)去:

<!DOCTYPE html> <html> <head>     <title>SimpleTODO</title>           <link rel="stylesheet" href="css/reset.css" type="text/css" />     <link rel="stylesheet" href="css/bootstrap.min.css" type="text/css" />           <script src="js/jquery.min.js"></script>     <script src="js/jquery-ui-1.8.16.custom.min.js"></script>           <style>     body {          padding-top: 40px;      }      #main {          margin-top: 80px;          text-align: center;      }      </style> </head> <body>     <div class="topbar">         <div class="fill">             <div class="container">                 <a class="brand" href="index.php">SimpleTODO</a>             </div>         </div>     </div>     <div id="main" class="container">         <form class="form-stacked" method="POST" action="login.php">             <div class="row">                 <div class="span5 offset5">                     <label for="login_username">Username:</label>                     <input type="text" id="login_username" name="login_username" placeholder="username" />                                       <label for="login_password">Password:</label>                     <input type="password" id="login_password" name="login_password" placeholder="password" />                                       </div>             </div>             <div class="actions">                 <button type="submit" name="login_submit" class="btn primary large">Login or Register</button>             </div>         </form>     </div> </body> </html>

這段代碼的運(yùn)行結(jié)果看起來(lái)就像這樣:

如何創(chuàng)建以API為中心的Web應(yīng)用 
SimpleTODO的登錄頁(yè)

需要注意的是我在這里已經(jīng)包含了兩個(gè)JavaScript文件和兩個(gè)CSS文件:

  • reset.css是你的標(biāo)準(zhǔn)CSS重置腳本。我使用了meyerweb.com css reset.
     

  • bootstrap.min.css是Twitter Bootstrap
     

  • jquery.min.js是最新版的jQuery library
     

  • jquery-ui-1.8.16.custom.min.js是最新版的jQuery UI library

接下來(lái),我們創(chuàng)建login.php文件來(lái)存儲(chǔ)客戶(hù)端會(huì)話(huà)中的用戶(hù)名和密碼。

<?php  //get the form values  $username = $_POST['login_username'];  $userpass = $_POST['login_password'];  session_start();  $_SESSION['username'] = $username;  $_SESSION['userpass'] = $userpass;  header('Location: todo.php');  exit();

這里,我們簡(jiǎn)單地為用戶(hù)開(kāi)啟一次會(huì)話(huà),所依據(jù)的是用戶(hù)所提供的用戶(hù)名和密碼組合。這充當(dāng)了簡(jiǎn)單的組合密鑰,它允許用戶(hù)訪(fǎng)問(wèn)某個(gè)特定用戶(hù)名和密碼組合所存儲(chǔ)的TODO項(xiàng)。然后我們重定向至todo.php,那里是我們開(kāi)始與API服務(wù)器交互的地方。然而在我們開(kāi)始編寫(xiě)todo.php文件之前,先創(chuàng)建一個(gè) ApiCaller類(lèi),它將封裝我們所需的全部API調(diào)用方法,包括請(qǐng)求的加密。

創(chuàng)建apicaller.php,并把下面的代碼寫(xiě)進(jìn)去:

<?php  class ApiCaller  {      //some variables for the object      private $_app_id;      private $_app_key;      private $_api_url;            //construct an ApiCaller object, taking an      //APP ID, APP KEY and API URL parameter      public function __construct($app_id, $app_key, $api_url)      {          $this->_app_id = $app_id;          $this->_app_key = $app_key;          $this->_api_url = $api_url;      }            //send the request to the API server      //also encrypts the request, then checks      //if the results are valid      public function sendRequest($request_params)      {          //encrypt the request parameters          $enc_request = base64_encode(mcrypt_encrypt(MCRYPT_RIJNDAEL_256, $this->_app_key, json_encode($request_params), MCRYPT_MODE_ECB));                    //create the params array, which will          //be the POST parameters          $params = array();          $params['enc_request'] = $enc_request;          $params['app_id'] = $this->_app_id;                    //initialize and setup the curl handler          $ch = curl_init();          curl_setopt($ch, CURLOPT_URL, $this->_api_url);          curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);          curl_setopt($ch, CURLOPT_POST, count($params));          curl_setopt($ch, CURLOPT_POSTFIELDS, $params);           //execute the request          $result = curl_exec($ch);                    //json_decode the result          $result = @json_decode($result);                    //check if we're able to json_decode the result correctly          if( $result == false || isset($result['success']) == false ) {              throw new Exception('Request was not correct');          }                    //if there was an error in the request, throw an exception          if( $result['success'] == false ) {              throw new Exception($result['errormsg']);          }                    //if everything went great, return the data          return $result['data'];      }  }

我們將利用ApiCaller類(lèi)向我們的API服務(wù)器發(fā)送請(qǐng)求。這樣,所有必需的加密和cURL初始化代碼將會(huì)寫(xiě)在一個(gè)地方,我們就不用重復(fù)代碼了。

  • __construct函數(shù)接受三個(gè)參數(shù):

  1. $app_id&mdash;&mdash;客戶(hù)端的APP ID(瀏覽器端是APP001
     

  2. $app_key&mdash;&mdash;客戶(hù)端的APP KEY(瀏覽器端是28e336ac6c9423d946ba02d19c6a2632
     

  3. $api_url&mdash;&mdash;API服務(wù)器的URL,此處為http://localhost/simpletodo_api/

  • sendRequest()函數(shù):

  1. 利用mcrypt庫(kù)以API服務(wù)對(duì)其解密的同樣方式來(lái)對(duì)請(qǐng)求參數(shù)進(jìn)行加密

  2. 生成發(fā)往API服務(wù)器的$_POST參數(shù)

  3. 通過(guò)cURL執(zhí)行API調(diào)用

  4. 查驗(yàn)API調(diào)用的結(jié)果是否正確

  5. 當(dāng)一切都按計(jì)劃進(jìn)行的時(shí)候返回?cái)?shù)據(jù)

現(xiàn)在,我們開(kāi)始寫(xiě)todo.php。首先,我們創(chuàng)建一些代碼來(lái)為密碼為test1234的用戶(hù)nikko(這是我們先前用來(lái)測(cè)試API服務(wù)器的那個(gè)用戶(hù)名/密碼組合)獲取當(dāng)前的todo項(xiàng)。

<?php  session_start();  include_once 'apicaller.php';   $apicaller = new ApiCaller('APP001', '28e336ac6c9423d946ba02d19c6a2632', 'http://localhost/simpletodo_api/');   $todo_items = $apicaller->sendRequest(array(      'controller' => 'todo',      'action' => 'read',      'username' => $_SESSION['username'],      'userpass' => $_SESSION['userpass']  ));   echo '';  var_dump($todo_items);

打開(kāi)index.php,以nikko/tes1234登錄,然后你應(yīng)該看到我們先前創(chuàng)建的TODO項(xiàng)的avar_dump()。

如何創(chuàng)建以API為中心的Web應(yīng)用

恭喜,你已經(jīng)成功地做好了一個(gè)向API服務(wù)器的API調(diào)用!在這段代碼中,我們已經(jīng):

  • 開(kāi)啟會(huì)話(huà),使我們擁有了對(duì)$_SESSION中的username以及userpass的訪(fǎng)問(wèn)權(quán)

  • 實(shí)例化了一個(gè)新的ApiCaller類(lèi),為其提供了APP ID,APP KEY,以及API服務(wù)器的URL
     

  • 通過(guò)sendRequest()方法發(fā)送了一個(gè)請(qǐng)求

現(xiàn)在,我們來(lái)重新格式化一下數(shù)據(jù),讓它們開(kāi)起來(lái)更好看些。向todo.php中添加下列HTML。別忘了移去var_dump()!

<!DOCTYPE html> <html> <head>     <title>SimpleTODO</title>           <link rel="stylesheet" href="css/reset.css" type="text/css" />     <link rel="stylesheet" href="css/bootstrap.min.css" type="text/css" />     <link rel="stylesheet" href="css/flick/jquery-ui-1.8.16.custom.css" type="text/css" />           <script src="js/jquery.min.js"></script>     <script src="js/jquery-ui-1.8.16.custom.min.js"></script>           <style>     body {          padding-top: 40px;      }      #main {          margin-top: 80px;      }            .textalignright {          text-align: right;      }            .marginbottom10 {          margin-bottom: 10px;      }      #newtodo_window {          text-align: left;          display: none;      }      </style>           <script>     $(document).ready(function() {          $("#todolist").accordion({              collapsible: true          });          $(".datepicker").datepicker();          $('#newtodo_window').dialog({              autoOpen: false,              height: 'auto',              width: 'auto',              modal: true          });          $('#newtodo').click(function() {              $('#newtodo_window').dialog('open');          });      });      </script> </head> <body>     <div class="topbar">         <div class="fill">             <div class="container">                 <a class="brand" href="index.php">SimpleTODO</a>             </div>         </div>     </div>     <div id="main" class="container">         <div class="textalignright marginbottom10">             <span id="newtodo" class="btn info">Create a new TODO item</span>             <div id="newtodo_window" title="Create a new TODO item">                 <form method="POST" action="new_todo.php">                     <p>Title:<br /><input type="text" class="title" name="title" placeholder="TODO title" /></p>                     <p>Date Due:<br /><input type="text" class="datepicker" name="due_date" placeholder="MM/DD/YYYY" /></p>                     <p>Description:<br /><textarea class="description" name="description"></textarea></p>                     <div class="actions">                         <input type="submit" value="Create" name="new_submit" class="btn primary" />                     </div>                 </form>             </div>         </div>         <div id="todolist">             <?php foreach($todo_items as $todo): ?>             <h4><a href="#"><?php echo $todo->title; ?></a></h4>             <div>                 <form method="POST" action="update_todo.php">                 <div class="textalignright">                     <a href="delete_todo.php?todo_id=<?php echo $todo->todo_id; ?>">Delete</a>                 </div>                 <div>                     <p>Date Due:<br /><input type="text" id="datepicker_<?php echo $todo->todo_id; ?>" class="datepicker" name="due_date" value="12/09/2011" /></p>                     <p>Description:<br /><textarea class="span8" id="description_<?php echo $todo->todo_id; ?>" class="description" name="description"><?php echo $todo->description; ?></textarea></p>                 </div>                 <div class="textalignright">                     <?php if( $todo->is_done == 'false' ): ?>                     <input type="hidden" value="false" name="is_done" />                     <input type="submit" class="btn" value="Mark as Done?" name="markasdone_button" />                     <?php else: ?>                     <input type="hidden" value="true" name="is_done" />                     <input type="button" class="btn success" value="Done!" name="done_button" />                     <?php endif; ?>                     <input type="hidden" value="<?php echo $todo->todo_id; ?>" name="todo_id" />                     <input type="hidden" value="<?php echo $todo->title; ?>" name="title" />                     <input type="submit" class="btn primary" value="Save Changes" name="update_button" />                 </div>                 </form>             </div>             <?php endforeach; ?>         </div>     </div> </body> </html>

這段代碼的運(yùn)行結(jié)果如下:

如何創(chuàng)建以API為中心的Web應(yīng)用

很酷哈?但它目前啥也干不了,那么讓我們開(kāi)始添加一些功能吧。我將為new_todo.php提供代碼,它們調(diào)用todo/createAPI調(diào)用來(lái)創(chuàng)建新的TODO項(xiàng)。創(chuàng)建其他頁(yè)(update_todo.php和delete_todo.php)應(yīng)該與此十分相似,因此我把它們留給你。打開(kāi)new_todo.php,然后把下面的代碼添進(jìn)去:

<?php  session_start();  include_once 'apicaller.php';   $apicaller = new ApiCaller('APP001', '28e336ac6c9423d946ba02d19c6a2632', 'http://localhost/simpletodo_api/');   $new_item = $apicaller->sendRequest(array(      'controller' => 'todo',      'action' => 'create',      'title' => $_POST['title'],      'due_date' => $_POST['due_date'],      'description' => $_POST['description'],      'username' => $_SESSION['username'],      'userpass' => $_SESSION['userpass']  ));   header('Location: todo.php');  exit();  ?>

正如你所看到的,new_todo.php頁(yè)再次使用了ApiCaller調(diào)用來(lái)簡(jiǎn)化向API服務(wù)器所發(fā)送的 todo/create請(qǐng)求。這主要完成了與之前相同的事情:

  • 開(kāi)啟一個(gè)會(huì)話(huà),以使其獲得對(duì)存儲(chǔ)于$_SESSION中的$username和$userpass的訪(fǎng)問(wèn)權(quán)

  • 實(shí)例化一個(gè)新的ApiCaller類(lèi),為它提供APP ID, APP KEY,以及API服務(wù)器的URL

  • 通過(guò)sendRequest()方法發(fā)送請(qǐng)求

  • 重定向回todo.php

如何創(chuàng)建以API為中心的Web應(yīng)用

恭喜,它好用了!你已經(jīng)成功地創(chuàng)建了一個(gè)以API為中心的應(yīng)用!

結(jié)論

圍繞API創(chuàng)建并開(kāi)發(fā)應(yīng)用具有如此之多的優(yōu)勢(shì)。想創(chuàng)建一個(gè)Android版的SimpleTODO?你需要的所有功能都已經(jīng)在API服務(wù)器上了,所以你所要做的就是創(chuàng)建客戶(hù)端!想重構(gòu)或者優(yōu)化某些類(lèi)?沒(méi)問(wèn)題&mdash;&mdash;只要確保輸出相同即可。想添加更多的功能?你可以在不影響任何客戶(hù)端代碼的前提下做到!

盡管存在著某些像是更長(zhǎng)的開(kāi)發(fā)時(shí)間或者更加復(fù)雜,但是以這種方式開(kāi)發(fā)網(wǎng)絡(luò)應(yīng)用的優(yōu)勢(shì)卻遠(yuǎn)比其劣勢(shì)更重要。今天的這種開(kāi)發(fā)由我們自己權(quán)衡取舍,從而使我們能夠在將來(lái)獲益。

關(guān)于如何創(chuàng)建以API為中心的Web應(yīng)用問(wèn)題的解答就分享到這里了,希望以上內(nèi)容可以對(duì)大家有一定的幫助,如果你還有很多疑惑沒(méi)有解開(kāi),可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI