国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

目錄
SSL 無(wú)處不在
JSON 中間件
REST API 的關(guān)鍵組件是什麼?
如何保護(hù)我的 REST API?
如何對(duì)我的 REST API 進(jìn)行版本控制?
如何在 REST API 中處理錯(cuò)誤?
如何測(cè)試我的 REST API?
如何記錄我的 REST API?
如何設(shè)計(jì) RESTful API?
如何在我的 REST API 中分頁(yè)結(jié)果?
如何限制我的 REST API 的速率?
如何部署我的 REST API?
首頁(yè) 後端開(kāi)發(fā) php教程 從頭開(kāi)始構(gòu)建REST API:簡(jiǎn)介

從頭開(kāi)始構(gòu)建REST API:簡(jiǎn)介

Feb 20, 2025 am 11:48 AM

Build a REST API from Scratch: An Introduction

當(dāng)前的互聯(lián)網(wǎng)生態(tài)系統(tǒng)已被 API 徹底改變,這是有充分理由的。通過(guò)在產(chǎn)品或服務(wù)中使用第三方 API,您可以訪問(wèn)大量有用的功能——例如身份驗(yàn)證或存儲(chǔ)服務(wù)——這些功能對(duì)您和您的用戶都有利。通過(guò)公開(kāi)您自己的 API,您的應(yīng)用程序?qū)⒊蔀椤敖M合的一部分”,並以您從未想過(guò)的方式使用……當(dāng)然,如果您以正確的方式這樣做。在這個(gè)由兩部分組成的系列文章中,我將向您展示如何使用一系列真實(shí)的最佳實(shí)踐為您的 PHP 應(yīng)用程序創(chuàng)建 RESTful API 層。本項(xiàng)目完整的源代碼將在第 2 部分的結(jié)尾提供。

關(guān)鍵要點(diǎn)

  • REST API 對(duì)現(xiàn)代 Web 服務(wù)至關(guān)重要,它為開(kāi)發(fā)人員提供了一個(gè)用戶友好的界面來(lái)訪問(wèn)和操作應(yīng)用程序數(shù)據(jù)。
  • 文檔至關(guān)重要;它應(yīng)該從總結(jié) API 範(fàn)圍並詳細(xì)說(shuō)明訪問(wèn)點(diǎn)和方法的 README 文件開(kāi)始。
  • Slim Framework 與 Idiorm 和 Monolog 等工具結(jié)合使用,可以利用強(qiáng)大的路由和中間件集成功能來(lái)促進(jìn)高效的 API 開(kāi)發(fā)。
  • 實(shí)施 HTTPS 可確保安全通信,防止未經(jīng)授權(quán)訪問(wèn)客戶端和服務(wù)器之間傳輸?shù)臄?shù)據(jù)。
  • 以 JSON 格式實(shí)現(xiàn)結(jié)構(gòu)化錯(cuò)誤處理可增強(qiáng) API 的可用性,提供清晰的錯(cuò)誤消息和代碼,有助於調(diào)試和集成。
  • 通過(guò)令牌優(yōu)先於基本身份驗(yàn)證以及 JSON 處理等中間件進(jìn)行身份驗(yàn)證對(duì)於有效地保護(hù)和管理 API 交互至關(guān)重要。

REST:開(kāi)發(fā)人員友好的 UI

首先,API 是開(kāi)發(fā)人員的用戶界面,因此它必須友好、簡(jiǎn)單、易於使用,當(dāng)然也要令人愉快;否則,它最終將成為另一個(gè)數(shù)字垃圾。即使只是一個(gè)簡(jiǎn)單但寫得很好的 README 文件,文檔也是一個(gè)良好的開(kāi)端。我們需要最少的信息是服務(wù)範(fàn)圍的摘要以及方法和訪問(wèn)點(diǎn)的列表。一個(gè)好的摘要可以是:> 我們的應(yīng)用程序是一個(gè)簡(jiǎn)單的聯(lián)繫人列表服務(wù),用於管理具有關(guān)聯(lián)筆記的聯(lián)繫人。它有兩種對(duì)像類型,聯(lián)繫人(contacts)和筆記(notes)。每個(gè)聯(lián)繫人都有基本屬性,例如名字、姓氏和電子郵件地址。此外,每個(gè)聯(lián)繫人可以有多個(gè)與之關(guān)聯(lián)的 Markdown 格式的筆記。

然後,最好列出我們將要實(shí)現(xiàn)的所有資源和操作。這可以被視為可視化應(yīng)用程序線框圖的等效項(xiàng)。遵循 REST 的關(guān)鍵原則,每個(gè)資源都由一個(gè) URL 表示,其中操作是用於訪問(wèn)它的 HTTP 方法。例如,GET /api/contacts/12 將檢索 ID 為 12 的聯(lián)繫人,而 PUT /api/contacts/12 將更新相同的聯(lián)繫人。完整的 method 列表如下所示:

<code>URL             HTTP Method  Operation
/api/contacts   GET          返回聯(lián)系人數(shù)組
/api/contacts/:id GET          返回 ID 為 :id 的聯(lián)系人
/api/contacts   POST         添加一個(gè)新聯(lián)系人并返回它(添加了 id 屬性)
/api/contacts/:id PUT          更新 ID 為 :id 的聯(lián)系人
/api/contacts/:id PATCH        部分更新 ID 為 :id 的聯(lián)系人
/api/contacts/:id DELETE       刪除 ID 為 :id 的聯(lián)系人

/api/contacts/:id/star PUT    將 ID 為 :id 的聯(lián)系人添加到收藏夾
/api/contacts/:id/star DELETE 從收藏夾中刪除 ID 為 :id 的聯(lián)系人

/api/contacts/:id/notes GET   返回 ID 為 :id 的聯(lián)系人的筆記
/api/contacts/:id/notes/:nid GET   返回 ID 為 :id 的聯(lián)系人的 ID 為 :nid 的筆記
/api/contacts/:id/notes POST  為 ID 為 :id 的聯(lián)系人添加新筆記
/api/contacts/:id/notes/:nid PUT   更新 ID 為 :id 的聯(lián)系人的 ID 為 :nid 的筆記
/api/contacts/:id/notes/:nid PATCH  部分更新 ID 為 :id 的聯(lián)系人的 ID 為 :nid 的筆記
/api/contacts/:id/notes/:nid DELETE 刪除 ID 為 :id 的聯(lián)系人的 ID 為 :nid 的筆記</code>

對(duì)於更完整和專業(yè)的文檔,您可以考慮使用 Swagger、apiDoc 或 Google APIs Discovery Service 等工具:您的用戶會(huì)喜歡您的!

工具和設(shè)置

我將用來(lái)構(gòu)建 API 的主要工具是 Slim Framework。為什麼? > [它] 幫助您快速編寫簡(jiǎn)單而強(qiáng)大的 Web 應(yīng)用程序和 API。

這是真的。其強(qiáng)大的路由功能使使用GET 和POST 以外的方法變得容易,它提供對(duì)HTTP 方法覆蓋的內(nèi)置支持(通過(guò)HTTP 標(biāo)頭和隱藏的POST 字段),並且可以與中間件和額外功能掛鉤,使應(yīng)用程序和API 開(kāi)發(fā)真正變得容易。與 Slim 一起,我使用 Idiorm 訪問(wèn)數(shù)據(jù)庫(kù)層,使用 Monolog 進(jìn)行日誌記錄。因此,我們的 composer.json 文件將如下所示:

{
  "name": "yourname/my-contacts",
  "description": "Simple RESTful API for contacts management",
  "license": "MIT",
  "authors": [
    {
      "name": "Your Name",
      "email": "you@yourdomain.com"
    }
  ],
  "require": {
    "slim/slim": "*",
    "slim/extras": "*",
    "slim/middleware": "*",
    "monolog/monolog": "*",
    "j4mie/paris": "*",
    "flynsarmy/slim-monolog": "*"
  },
  "archive": {
    "exclude": ["vendor", ".DS_Store", "*.log"]
  },
  "autoload": {
    "psr-0": {
      "API": "lib/"
    }
  }
}

slim/extras 和 slim/middleware 包提供了諸如內(nèi)容類型解析和基本身份驗(yàn)證之類的有用功能。我們的自定義類位於 API 命名空間下,位於 lib 目錄中。此時(shí),我們的工作目錄結(jié)構(gòu)如下所示:

<code>bootstrap.php
composer.json
README.md
bin/
    import
    install
lib/
    API/
public/
    .htaccess
    index.php
share/
    config/
        default.php
    db/
    logs/
    sql/
        data/
            contacts.sql
            users.sql
        tables/
            contacts.sql
            notes.sql
            users.sql
        ssl/
            mysitename.crt
            mysitename.key</code>

我們的應(yīng)用程序的前端控制器是 public/index.php,所有非文件或目錄流量都通過(guò)標(biāo)準(zhǔn) URL 重寫規(guī)則重定向到此處。然後,我將所有初始化代碼放在 bootstrap.php 中,我們稍後會(huì)看到。 share 目錄包含數(shù)據(jù),例如日誌、配置文件、SQLite 數(shù)據(jù)庫(kù)和轉(zhuǎn)儲(chǔ)文件以及 SSL 證書。 bin 目錄包含使用提供的 .sql 文件創(chuàng)建數(shù)據(jù)庫(kù)和導(dǎo)入一些數(shù)據(jù)的實(shí)用程序腳本。

SSL 無(wú)處不在

我們的 API 只能在 HTTPS 模式下訪問(wèn),無(wú)需重定向。這簡(jiǎn)化了身份驗(yàn)證邏輯並防止配置不當(dāng)?shù)目蛻舳嗽L問(wèn)未加密的端點(diǎn)。設(shè)置此方法最簡(jiǎn)單和最合乎邏輯的方法是直接作用於 Web 服務(wù)器或通過(guò)代理服務(wù)器。我使用舊的可靠的 Apache 來(lái)執(zhí)行此操作,我的虛擬主機(jī)文件如下所示:

<Directory>

  # Required for mod_rewrite in .htaccess
  AllowOverride FileInfo

  Options All -Indexes

  DirectoryIndex index.php index.shtml index.html

  <IfModule php5_module="">
    # For Development only!
    php_flag display_errors On
  </IfModule>

  # Enable gzip compression
  <IfModule filter_module="">
    AddOutputFilterByType DEFLATE application/json
  </IfModule>

  Order deny,allow
  Deny from all
  Allow from 127.0.0.1
</Directory>

<VirtualHost *:80>
  ServerAdmin you@yourdomain.com
  DocumentRoot "/path/to/MyApp/public"
  ServerName myapp.dev

  <IfModule rewrite_module="">
    RewriteEngine on

    ## Throw a 403 (forbidden) status for non secure requests
    RewriteCond %{HTTPS} off
    RewriteRule ^.*$ - [L,R=403]
  </IfModule>
</VirtualHost>

<IfModule ssl_module="">

  NameVirtualHost *:443

  Listen 443
  SSLRandomSeed startup builtin
  SSLRandomSeed connect builtin

  <VirtualHost *:443>
    ServerAdmin you@yourdomain.com
    DocumentRoot "/path/to/MyApp/public"
    ServerName myapp.dev

    SSLEngine on
    SSLCertificateFile /path/to/MyApp/share/ssl/mysitename.crt
    SSLCertificateKeyFile /path/to/MyApp/share/ssl/mysitename.key

    SetEnv SLIM_MODE development

  </VirtualHost>
</IfModule>

首先定義目錄設(shè)置,以便它們與我們站點(diǎn)的 HTTP 和 HTTPS 版本通用。在非安全主機(jī)配置中,我使用 mod_rewrite 為任何非安全連接發(fā)出 403 禁止錯(cuò)誤,然後在安全部分中,我使用我的自簽名證書設(shè)置 SSL,以及告訴 Slim 當(dāng)前應(yīng)用程序模式的 SLIM_ENV 變量。有關(guān)如何在 Apache 上創(chuàng)建自簽名證書並安裝它的更多信息,請(qǐng)參閱 SSLShopper 上的這篇文章?,F(xiàn)在我們有了明確的目標(biāo)、基本目錄結(jié)構(gòu)和服務(wù)器設(shè)置,讓我們運(yùn)行 composer.phar install 並開(kāi)始編寫一些代碼。

引導(dǎo)程序和前端控制器

如前所述,bootstrap.php 文件負(fù)責(zé)加載我們的應(yīng)用程序設(shè)置和自動(dòng)加載器設(shè)置。

<code>URL             HTTP Method  Operation
/api/contacts   GET          返回聯(lián)系人數(shù)組
/api/contacts/:id GET          返回 ID 為 :id 的聯(lián)系人
/api/contacts   POST         添加一個(gè)新聯(lián)系人并返回它(添加了 id 屬性)
/api/contacts/:id PUT          更新 ID 為 :id 的聯(lián)系人
/api/contacts/:id PATCH        部分更新 ID 為 :id 的聯(lián)系人
/api/contacts/:id DELETE       刪除 ID 為 :id 的聯(lián)系人

/api/contacts/:id/star PUT    將 ID 為 :id 的聯(lián)系人添加到收藏夾
/api/contacts/:id/star DELETE 從收藏夾中刪除 ID 為 :id 的聯(lián)系人

/api/contacts/:id/notes GET   返回 ID 為 :id 的聯(lián)系人的筆記
/api/contacts/:id/notes/:nid GET   返回 ID 為 :id 的聯(lián)系人的 ID 為 :nid 的筆記
/api/contacts/:id/notes POST  為 ID 為 :id 的聯(lián)系人添加新筆記
/api/contacts/:id/notes/:nid PUT   更新 ID 為 :id 的聯(lián)系人的 ID 為 :nid 的筆記
/api/contacts/:id/notes/:nid PATCH  部分更新 ID 為 :id 的聯(lián)系人的 ID 為 :nid 的筆記
/api/contacts/:id/notes/:nid DELETE 刪除 ID 為 :id 的聯(lián)系人的 ID 為 :nid 的筆記</code>

首先,我獲取當(dāng)前環(huán)境。如果存在名為 .php 的文件,則加載它,否則加載默認(rèn)配置文件。 Slim 特定的設(shè)置存儲(chǔ)在 $config['app'] 數(shù)組中,並傳遞給擴(kuò)展基本 Slim 對(duì)象的應(yīng)用程序的構(gòu)造函數(shù)(可選但推薦)。例如,語(yǔ)句:

{
  "name": "yourname/my-contacts",
  "description": "Simple RESTful API for contacts management",
  "license": "MIT",
  "authors": [
    {
      "name": "Your Name",
      "email": "you@yourdomain.com"
    }
  ],
  "require": {
    "slim/slim": "*",
    "slim/extras": "*",
    "slim/middleware": "*",
    "monolog/monolog": "*",
    "j4mie/paris": "*",
    "flynsarmy/slim-monolog": "*"
  },
  "archive": {
    "exclude": ["vendor", ".DS_Store", "*.log"]
  },
  "autoload": {
    "psr-0": {
      "API": "lib/"
    }
  }
}

配置一個(gè) Monolog 記錄器,該記錄器寫入 app/path/share/logs/EnvName_YYYY-mm-dd.log 的文件。然後,在一些改進(jìn)之後(您可以在源代碼中看到它們),我獲取生成的日誌寫入器並嘗試連接到數(shù)據(jù)庫(kù):

<code>bootstrap.php
composer.json
README.md
bin/
    import
    install
lib/
    API/
public/
    .htaccess
    index.php
share/
    config/
        default.php
    db/
    logs/
    sql/
        data/
            contacts.sql
            users.sql
        tables/
            contacts.sql
            notes.sql
            users.sql
        ssl/
            mysitename.crt
            mysitename.key</code>

最後,我將所需的中間件添加到我的應(yīng)用程序?qū)嵗小?Slim 的中間件就像洋蔥的層一樣,您添加的第一個(gè)中間件將是最內(nèi)層的,因此我們中間件的順序很重要。我在我們的API 中使用以下中間件:- 緩存(最內(nèi)層);- ContentTypes:解析來(lái)自客戶端的JSON 格式的正文;- RateLimit:管理用戶的API 限制;- JSON:“僅JSON 響應(yīng)”和“ JSON 編碼正文”最佳實(shí)踐的實(shí)用程序中間件;- 身份驗(yàn)證(最外層)。我們將編寫所有這些,除了預(yù)先存在的 ContentTypes。在 bootstrap 文件的末尾,我定義了兩個(gè)全局變量 $app(應(yīng)用程序?qū)嵗┖?$log(日誌寫入器)。該文件由我們的前端控制器 index.php 加載,在該文件中發(fā)生神奇的事情。

路由結(jié)構(gòu)

Slim 有一個(gè)名為 Route Groups 的不錯(cuò)的功能。使用此功能,我們可以像這樣定義我們的應(yīng)用程序路由:

<Directory>

  # Required for mod_rewrite in .htaccess
  AllowOverride FileInfo

  Options All -Indexes

  DirectoryIndex index.php index.shtml index.html

  <IfModule php5_module="">
    # For Development only!
    php_flag display_errors On
  </IfModule>

  # Enable gzip compression
  <IfModule filter_module="">
    AddOutputFilterByType DEFLATE application/json
  </IfModule>

  Order deny,allow
  Deny from all
  Allow from 127.0.0.1
</Directory>

<VirtualHost *:80>
  ServerAdmin you@yourdomain.com
  DocumentRoot "/path/to/MyApp/public"
  ServerName myapp.dev

  <IfModule rewrite_module="">
    RewriteEngine on

    ## Throw a 403 (forbidden) status for non secure requests
    RewriteCond %{HTTPS} off
    RewriteRule ^.*$ - [L,R=403]
  </IfModule>
</VirtualHost>

<IfModule ssl_module="">

  NameVirtualHost *:443

  Listen 443
  SSLRandomSeed startup builtin
  SSLRandomSeed connect builtin

  <VirtualHost *:443>
    ServerAdmin you@yourdomain.com
    DocumentRoot "/path/to/MyApp/public"
    ServerName myapp.dev

    SSLEngine on
    SSLCertificateFile /path/to/MyApp/share/ssl/mysitename.crt
    SSLCertificateKeyFile /path/to/MyApp/share/ssl/mysitename.key

    SetEnv SLIM_MODE development

  </VirtualHost>
</IfModule>

我創(chuàng)建了兩個(gè)嵌套組 /api 和 /v1,因此我們可以輕鬆遵守“URL 中的版本控制”最佳實(shí)踐。我還為 /api/ 創(chuàng)建了一些可選路由,其中可能包含用戶可讀的內(nèi)容,以及一個(gè)通用的根 URL(/)URL,在現(xiàn)實(shí)世界中,該 URL 可能包含應(yīng)用程序的公共用戶界面。

JSON 中間件

我最初的方法是在 /v1 組內(nèi)使用路由中間件(另一種 Slim 中間件),用於身份驗(yàn)證和 JSON 請(qǐng)求/響應(yīng),但我發(fā)現(xiàn)使用經(jīng)典中間件更實(shí)用和簡(jiǎn)潔。如前所述,中間件是繼承自 SlimMiddleware 的類的實(shí)例。 Slim 中間件的 call() 方法是操作發(fā)生的地方,當(dāng)中間件作為全局中間件鏈接時(shí),它會(huì)自動(dòng)執(zhí)行,使用 $app->add() 方法。

// Init application mode
if (empty($_ENV['SLIM_MODE'])) {
  $_ENV['SLIM_MODE'] = (getenv('SLIM_MODE'))
    ? getenv('SLIM_MODE') : 'development';
}

// Init and load configuration
$config = array();

$configFile = dirname(__FILE__) . '/share/config/'
  . $_ENV['SLIM_MODE'] . '.php';

if (is_readable($configFile)) {
  require_once $configFile;
} else {
  require_once dirname(__FILE__) . '/share/config/default.php';
}

// Create Application
$app = new API\Application($config['app']);

我們的 JSON 中間件實(shí)現(xiàn)了兩個(gè)最佳實(shí)踐:“僅 JSON 響應(yīng)”和“JSON 編碼正文”。方法如下:

<code>URL             HTTP Method  Operation
/api/contacts   GET          返回聯(lián)系人數(shù)組
/api/contacts/:id GET          返回 ID 為 :id 的聯(lián)系人
/api/contacts   POST         添加一個(gè)新聯(lián)系人并返回它(添加了 id 屬性)
/api/contacts/:id PUT          更新 ID 為 :id 的聯(lián)系人
/api/contacts/:id PATCH        部分更新 ID 為 :id 的聯(lián)系人
/api/contacts/:id DELETE       刪除 ID 為 :id 的聯(lián)系人

/api/contacts/:id/star PUT    將 ID 為 :id 的聯(lián)系人添加到收藏夾
/api/contacts/:id/star DELETE 從收藏夾中刪除 ID 為 :id 的聯(lián)系人

/api/contacts/:id/notes GET   返回 ID 為 :id 的聯(lián)系人的筆記
/api/contacts/:id/notes/:nid GET   返回 ID 為 :id 的聯(lián)系人的 ID 為 :nid 的筆記
/api/contacts/:id/notes POST  為 ID 為 :id 的聯(lián)系人添加新筆記
/api/contacts/:id/notes/:nid PUT   更新 ID 為 :id 的聯(lián)系人的 ID 為 :nid 的筆記
/api/contacts/:id/notes/:nid PATCH  部分更新 ID 為 :id 的聯(lián)系人的 ID 為 :nid 的筆記
/api/contacts/:id/notes/:nid DELETE 刪除 ID 為 :id 的聯(lián)系人的 ID 為 :nid 的筆記</code>

我們可以將根路徑傳遞給中間件構(gòu)造函數(shù)。在這種情況下,我傳遞 /api/v1,以便我們的中間件僅應(yīng)用於我們站點(diǎn)的 API 部分。如果當(dāng)前路徑與響應(yīng)內(nèi)容類型標(biāo)頭匹配,則強(qiáng)制響應(yīng)內(nèi)容類型標(biāo)頭為 application/json,然後我檢查請(qǐng)求方法。如果請(qǐng)求方法是啟用寫入的請(qǐng)求方法之一(PUT、POST、PATCH),則請(qǐng)求內(nèi)容類型標(biāo)頭必須為 application/json,否則應(yīng)用程序?qū)⑼顺鰜K顯示 415 Unsupported Media Type HTTP 狀態(tài)代碼。如果一切正常,語(yǔ)句 $this->next->call() 將運(yùn)行鏈中的下一個(gè)中間件。

身份驗(yàn)證

由於我們的應(yīng)用程序默認(rèn)情況下將在HTTPS 上運(yùn)行,因此我決定使用令牌優(yōu)先於基本身份驗(yàn)證的方法:API 密鑰發(fā)送到基本HTTP AUTH 標(biāo)頭的用戶名字段中(不需要密碼)。為此,我編寫了一個(gè)名為 TokenOverBasicAuth 的 Slim 中間件類,方法是修改現(xiàn)有的 Slim HttpBasicAuth。此中間件首先在鏈中運(yùn)行,因此它作為最後一個(gè)添加,並且它在構(gòu)造函數(shù)中採(cǎi)用可選的根路徑參數(shù)。

{
  "name": "yourname/my-contacts",
  "description": "Simple RESTful API for contacts management",
  "license": "MIT",
  "authors": [
    {
      "name": "Your Name",
      "email": "you@yourdomain.com"
    }
  ],
  "require": {
    "slim/slim": "*",
    "slim/extras": "*",
    "slim/middleware": "*",
    "monolog/monolog": "*",
    "j4mie/paris": "*",
    "flynsarmy/slim-monolog": "*"
  },
  "archive": {
    "exclude": ["vendor", ".DS_Store", "*.log"]
  },
  "autoload": {
    "psr-0": {
      "API": "lib/"
    }
  }
}

該方法在 PHP_AUTH_USER 請(qǐng)求標(biāo)頭中搜索 auth 令牌,如果它不存在或無(wú)效,則將 401 禁止?fàn)顟B(tài)和身份驗(yàn)證標(biāo)頭傳遞給客戶端。 verify() 方法是受保護(hù)的,因此可以由子類覆蓋;我在這裡的版本很簡(jiǎn)單:

<code>bootstrap.php
composer.json
README.md
bin/
    import
    install
lib/
    API/
public/
    .htaccess
    index.php
share/
    config/
        default.php
    db/
    logs/
    sql/
        data/
            contacts.sql
            users.sql
        tables/
            contacts.sql
            notes.sql
            users.sql
        ssl/
            mysitename.crt
            mysitename.key</code>

在這裡,我只是檢查 users 表中 API 密鑰的存在,如果我找到一個(gè)有效的用戶,則將其添加到應(yīng)用程序上下文中,以便與下一層(RateLimit)一起使用。您可以修改或擴(kuò)展此類以注入您自己的身份驗(yàn)證邏輯或使用 OAuth 模塊。有關(guān) OAuth 的更多信息,請(qǐng)參閱 Jamie Munro 的文章。

可使用的錯(cuò)誤有效負(fù)載

如果可能的話,我們的 API 應(yīng)該以可使用的格式顯示有用的錯(cuò)誤消息,最好以 JSON 表示形式。我們需要一個(gè)包含錯(cuò)誤代碼和消息的最小有效負(fù)載。此外,驗(yàn)證錯(cuò)誤需要更多細(xì)分。使用 Slim,我們可以分別使用 $app->notFound() 和 $app->error() 方法重新定義 404 錯(cuò)誤和服務(wù)器錯(cuò)誤。

<code>URL             HTTP Method  Operation
/api/contacts   GET          返回聯(lián)系人數(shù)組
/api/contacts/:id GET          返回 ID 為 :id 的聯(lián)系人
/api/contacts   POST         添加一個(gè)新聯(lián)系人并返回它(添加了 id 屬性)
/api/contacts/:id PUT          更新 ID 為 :id 的聯(lián)系人
/api/contacts/:id PATCH        部分更新 ID 為 :id 的聯(lián)系人
/api/contacts/:id DELETE       刪除 ID 為 :id 的聯(lián)系人

/api/contacts/:id/star PUT    將 ID 為 :id 的聯(lián)系人添加到收藏夾
/api/contacts/:id/star DELETE 從收藏夾中刪除 ID 為 :id 的聯(lián)系人

/api/contacts/:id/notes GET   返回 ID 為 :id 的聯(lián)系人的筆記
/api/contacts/:id/notes/:nid GET   返回 ID 為 :id 的聯(lián)系人的 ID 為 :nid 的筆記
/api/contacts/:id/notes POST  為 ID 為 :id 的聯(lián)系人添加新筆記
/api/contacts/:id/notes/:nid PUT   更新 ID 為 :id 的聯(lián)系人的 ID 為 :nid 的筆記
/api/contacts/:id/notes/:nid PATCH  部分更新 ID 為 :id 的聯(lián)系人的 ID 為 :nid 的筆記
/api/contacts/:id/notes/:nid DELETE 刪除 ID 為 :id 的聯(lián)系人的 ID 為 :nid 的筆記</code>

找不到錯(cuò)誤更簡(jiǎn)單:首先我獲取請(qǐng)求的媒體類型,然後 $isAPI 標(biāo)誌告訴我當(dāng)前 URL 是否位於 /api/v* 組下。如果客戶端請(qǐng)求 API URL 或發(fā)送 JSON 內(nèi)容類型標(biāo)頭,我將返回 JSON 輸出,否則我可以呈現(xiàn)模板或簡(jiǎn)單地打印一些靜態(tài) HTML,如本例所示。其他錯(cuò)誤有點(diǎn)棘手,當(dāng)出現(xiàn)異常時(shí)會(huì)觸發(fā) $app->error() 方法,Slim 將標(biāo)準(zhǔn) PHP 錯(cuò)誤轉(zhuǎn)換為 ErrorException 對(duì)象。我們需要一種方法向客戶端提供有用的錯(cuò)誤,而不會(huì)為了避免安全漏洞而暴露太多內(nèi)部機(jī)制。為此應(yīng)用程序,我創(chuàng)建了兩個(gè)自定義異常,APIException 和 APIExceptionValidationException,它們向公眾公開(kāi),所有其他異常類型都記錄在日誌中,並且僅在開(kāi)發(fā)模式下顯示。

{
  "name": "yourname/my-contacts",
  "description": "Simple RESTful API for contacts management",
  "license": "MIT",
  "authors": [
    {
      "name": "Your Name",
      "email": "you@yourdomain.com"
    }
  ],
  "require": {
    "slim/slim": "*",
    "slim/extras": "*",
    "slim/middleware": "*",
    "monolog/monolog": "*",
    "j4mie/paris": "*",
    "flynsarmy/slim-monolog": "*"
  },
  "archive": {
    "exclude": ["vendor", ".DS_Store", "*.log"]
  },
  "autoload": {
    "psr-0": {
      "API": "lib/"
    }
  }
}

$app->error() 方法接收拋出的異常作為參數(shù)。默認(rèn)情況下,我獲取所需的所有數(shù)據(jù)並填充 $error 數(shù)組,然後如果我在生產(chǎn)模式下,我將取消設(shè)置私有數(shù)據(jù)並使用通用數(shù)據(jù)重寫消息。自定義 ValidationException 類具有自定義 getData() 方法,該方法返回添加到最終有效負(fù)載的驗(yàn)證錯(cuò)誤數(shù)組。然後,根據(jù)請(qǐng)求以 JSON 或 HTML 顯示錯(cuò)誤。在 API 端,我們可以有一個(gè)簡(jiǎn)單的錯(cuò)誤,如下所示:

<code>bootstrap.php
composer.json
README.md
bin/
    import
    install
lib/
    API/
public/
    .htaccess
    index.php
share/
    config/
        default.php
    db/
    logs/
    sql/
        data/
            contacts.sql
            users.sql
        tables/
            contacts.sql
            notes.sql
            users.sql
        ssl/
            mysitename.crt
            mysitename.key</code>

或完整的驗(yàn)證錯(cuò)誤,如下所示:

<Directory>

  # Required for mod_rewrite in .htaccess
  AllowOverride FileInfo

  Options All -Indexes

  DirectoryIndex index.php index.shtml index.html

  <IfModule php5_module="">
    # For Development only!
    php_flag display_errors On
  </IfModule>

  # Enable gzip compression
  <IfModule filter_module="">
    AddOutputFilterByType DEFLATE application/json
  </IfModule>

  Order deny,allow
  Deny from all
  Allow from 127.0.0.1
</Directory>

<VirtualHost *:80>
  ServerAdmin you@yourdomain.com
  DocumentRoot "/path/to/MyApp/public"
  ServerName myapp.dev

  <IfModule rewrite_module="">
    RewriteEngine on

    ## Throw a 403 (forbidden) status for non secure requests
    RewriteCond %{HTTPS} off
    RewriteRule ^.*$ - [L,R=403]
  </IfModule>
</VirtualHost>

<IfModule ssl_module="">

  NameVirtualHost *:443

  Listen 443
  SSLRandomSeed startup builtin
  SSLRandomSeed connect builtin

  <VirtualHost *:443>
    ServerAdmin you@yourdomain.com
    DocumentRoot "/path/to/MyApp/public"
    ServerName myapp.dev

    SSLEngine on
    SSLCertificateFile /path/to/MyApp/share/ssl/mysitename.crt
    SSLCertificateKeyFile /path/to/MyApp/share/ssl/mysitename.key

    SetEnv SLIM_MODE development

  </VirtualHost>
</IfModule>

結(jié)論

我們現(xiàn)在已經(jīng)有了 API 的核心。在下一部分中,我們將添加一些內(nèi)容,以便擁有一個(gè)功能齊全的服務(wù)。在此期間,請(qǐng)隨時(shí)閱讀本部分中鏈接的文章——它們是關(guān)於有用 API 設(shè)計(jì)原則的寶庫(kù)。

關(guān)於從頭開(kāi)始構(gòu)建 REST API 的常見(jiàn)問(wèn)題解答 (FAQ)

REST API 的關(guān)鍵組件是什麼?

REST API 由幾個(gè)關(guān)鍵組件組成。首先是 HTTP 方法,它定義要執(zhí)行的操作類型。這些包括 GET、POST、PUT、DELETE 等。第二個(gè)組件是 URL 或 URI,它是資源標(biāo)識(shí)符。第三個(gè)組件是 HTTP 標(biāo)頭,它承載 HTTP 請(qǐng)求和響應(yīng)的元數(shù)據(jù)。第四個(gè)組件是正文或有效負(fù)載,它承載要傳輸?shù)膶?shí)際數(shù)據(jù)。最後,狀態(tài)代碼指示 HTTP 請(qǐng)求的成功或失敗。

如何保護(hù)我的 REST API?

保護(hù)您的 REST API 對(duì)於保護(hù)敏感數(shù)據(jù)至關(guān)重要。您可以使用各種方法,例如 API 密鑰、OAuth 或 JWT 進(jìn)行身份驗(yàn)證和授權(quán)。此外,始終使用 HTTPS 進(jìn)行數(shù)據(jù)傳輸,以確保數(shù)據(jù)完整性和機(jī)密性。定期更新和修補(bǔ)您的 API 及其依賴項(xiàng),以防範(fàn)漏洞。

如何對(duì)我的 REST API 進(jìn)行版本控制?

對(duì)您的 REST API 進(jìn)行版本控制允許您引入非破壞性更改,而不會(huì)影響現(xiàn)有客戶端。您可以通過(guò)在 URL 中包含版本號(hào)或使用自定義請(qǐng)求標(biāo)頭來(lái)對(duì) API 進(jìn)行版本控制。請(qǐng)記住記錄所有更改並告知您的 API 使用者新版本及其功能。

如何在 REST API 中處理錯(cuò)誤?

REST API 中正確的錯(cuò)誤處理提高了其可用性和可靠性。使用 HTTP 狀態(tài)代碼指示錯(cuò)誤類型。在響應(yīng)正文中包含錯(cuò)誤消息,以獲取有關(guān)錯(cuò)誤的更多詳細(xì)信息。這有助於客戶端了解出了什麼問(wèn)題以及如何解決問(wèn)題。

如何測(cè)試我的 REST API?

測(cè)試您的 REST API 可確保其按預(yù)期工作並可以處理各種場(chǎng)景。您可以使用 Postman 或 curl 等工具進(jìn)行手動(dòng)測(cè)試。對(duì)於自動(dòng)化測(cè)試,請(qǐng)考慮使用單元測(cè)試、集成測(cè)試和端到端測(cè)試。使用模擬服務(wù)器來(lái)模擬 API 響應(yīng)並測(cè)試您的 API 如何處理不同類型的響應(yīng)。

如何記錄我的 REST API?

良好的文檔使您的 REST API 易於理解和使用。包括有關(guān)端點(diǎn)、請(qǐng)求方法、請(qǐng)求參數(shù)、請(qǐng)求示例、響應(yīng)狀態(tài)代碼和響應(yīng)示例的詳細(xì)信息。您可以使用 Swagger 或 Postman 等工具來(lái)生成和託管您的 API 文檔。

如何設(shè)計(jì) RESTful API?

設(shè)計(jì) RESTful API 涉及規(guī)劃資源、端點(diǎn)和方法。對(duì)資源使用名詞,對(duì)操作使用 HTTP 方法。保持 API 簡(jiǎn)單直觀。使用狀態(tài)代碼指示請(qǐng)求的結(jié)果。使您的 API 無(wú)狀態(tài),這意味著每個(gè)請(qǐng)求都應(yīng)包含處理請(qǐng)求所需的所有信息。

如何在我的 REST API 中分頁(yè)結(jié)果?

分頁(yè)有助於限制單個(gè)響應(yīng)中返回的數(shù)據(jù)量。您可以使用諸如“page”和“l(fā)imit”之類的查詢參數(shù)來(lái)實(shí)現(xiàn)分頁(yè)。在響應(yīng)標(biāo)頭或正文中包含元數(shù)據(jù),以指示當(dāng)前頁(yè)、總頁(yè)數(shù)、總項(xiàng)目數(shù)等。

如何限制我的 REST API 的速率?

速率限制可保護(hù)您的 REST API 免受濫用並確保公平使用。您可以根據(jù) IP 地址、API 密鑰或用戶帳戶限制請(qǐng)求數(shù)量。使用 HTTP 標(biāo)頭將速率限制狀態(tài)傳達(dá)給客戶端。

如何部署我的 REST API?

您可以將您的 REST API 部署到服務(wù)器或云平臺(tái)上。在選擇部署選項(xiàng)時(shí),請(qǐng)考慮成本、可擴(kuò)展性和安全性等因素。使用持續(xù)集成和持續(xù)交付 (CI/CD) 工具來(lái)自動(dòng)化部署過(guò)程。監(jiān)控您的 API 性能和使用情況,以確保它滿足用戶的需求。

以上是從頭開(kāi)始構(gòu)建REST API:簡(jiǎn)介的詳細(xì)內(nèi)容。更多資訊請(qǐng)關(guān)注PHP中文網(wǎng)其他相關(guān)文章!

本網(wǎng)站聲明
本文內(nèi)容由網(wǎng)友自願(yuàn)投稿,版權(quán)歸原作者所有。本站不承擔(dān)相應(yīng)的法律責(zé)任。如發(fā)現(xiàn)涉嫌抄襲或侵權(quán)的內(nèi)容,請(qǐng)聯(lián)絡(luò)admin@php.cn

熱AI工具

Undress AI Tool

Undress AI Tool

免費(fèi)脫衣圖片

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅(qū)動(dòng)的應(yīng)用程序,用於創(chuàng)建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費(fèi)的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費(fèi)的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強(qiáng)大的PHP整合開(kāi)發(fā)環(huán)境

Dreamweaver CS6

Dreamweaver CS6

視覺(jué)化網(wǎng)頁(yè)開(kāi)發(fā)工具

SublimeText3 Mac版

SublimeText3 Mac版

神級(jí)程式碼編輯軟體(SublimeText3)

對(duì)基於PHP的API進(jìn)行版本控制的最佳實(shí)踐是什麼? 對(duì)基於PHP的API進(jìn)行版本控制的最佳實(shí)踐是什麼? Jun 14, 2025 am 12:27 AM

基於toversionaphp,useUrl deuseUrl specteringforclarityAndEsofRouting,單獨(dú)的codetoavoidConflicts,dremecateOldVersionswithClearCommunication,andConsiderCustomHeadeSerlySerallyWhennEnncelsy.startbyplacingtheversionIntheUrl(E.G.,epi/api/v

如何在PHP中實(shí)施身份驗(yàn)證和授權(quán)? 如何在PHP中實(shí)施身份驗(yàn)證和授權(quán)? Jun 20, 2025 am 01:03 AM

tosecurelyhandleauthenticationandationallizationInphp,lofterTheSesteps:1.AlwaysHashPasswordSwithPassword_hash()andverifyusingspasspassword_verify(),usepreparedStatatementStopreventsqlineptions,andStoreSeruserDatain usseruserDatain $ _sessiveferterlogin.2.implementrole-2.imaccessccsccccccccccccccccccccccccc.

PHP中的程序和麵向?qū)ο蟮木幊坦?fàn)例之間有什麼區(qū)別? PHP中的程序和麵向?qū)ο蟮木幊坦?fàn)例之間有什麼區(qū)別? Jun 14, 2025 am 12:25 AM

procemal and object-tiriendedprogromming(oop)inphpdiffersimplessintustructure,可重複使用性和datahandling.1.procedural-Progrogursmingusesfunctimesfunctionsormanized sequalized sequalized sequiential,poiperforsmallscripts.2.OpporganizesCodeOrganizescodeOdeIntsocloceSandObjects,ModelingReal-Worlden-Worlden

PHP中有哪些弱參考(弱圖),何時(shí)有用? PHP中有哪些弱參考(弱圖),何時(shí)有用? Jun 14, 2025 am 12:25 AM

PHPdoesnothaveabuilt-inWeakMapbutoffersWeakReferenceforsimilarfunctionality.1.WeakReferenceallowsholdingreferenceswithoutpreventinggarbagecollection.2.Itisusefulforcaching,eventlisteners,andmetadatawithoutaffectingobjectlifecycles.3.YoucansimulateaWe

如何在PHP中安全地處理文件上傳? 如何在PHP中安全地處理文件上傳? Jun 19, 2025 am 01:05 AM

要安全處理PHP中的文件上傳,核心在於驗(yàn)證文件類型、重命名文件並限制權(quán)限。 1.使用finfo_file()檢查真實(shí)MIME類型,僅允許特定類型如image/jpeg;2.用uniqid()生成隨機(jī)文件名,存儲(chǔ)至非Web根目錄;3.通過(guò)php.ini和HTML表單限製文件大小,設(shè)置目錄權(quán)限為0755;4.使用ClamAV掃描惡意軟件,增強(qiáng)安全性。這些步驟有效防止安全漏洞,確保文件上傳過(guò)程安全可靠。

如何與PHP的NOSQL數(shù)據(jù)庫(kù)(例如MongoDB,Redis)進(jìn)行交互? 如何與PHP的NOSQL數(shù)據(jù)庫(kù)(例如MongoDB,Redis)進(jìn)行交互? Jun 19, 2025 am 01:07 AM

是的,PHP可以通過(guò)特定擴(kuò)展或庫(kù)與MongoDB和Redis等NoSQL數(shù)據(jù)庫(kù)交互。首先,使用MongoDBPHP驅(qū)動(dòng)(通過(guò)PECL或Composer安裝)創(chuàng)建客戶端實(shí)例並操作數(shù)據(jù)庫(kù)及集合,支持插入、查詢、聚合等操作;其次,使用Predis庫(kù)或phpredis擴(kuò)展連接Redis,執(zhí)行鍵值設(shè)置與獲取,推薦phpredis用於高性能場(chǎng)景,Predis則便於快速部署;兩者均適用於生產(chǎn)環(huán)境且文檔完善。

PHP中==(鬆散比較)和===(嚴(yán)格的比較)之間有什麼區(qū)別? PHP中==(鬆散比較)和===(嚴(yán)格的比較)之間有什麼區(qū)別? Jun 19, 2025 am 01:07 AM

在PHP中,==與===的主要區(qū)別在於類型檢查的嚴(yán)格程度。 ==在比較前會(huì)進(jìn)行類型轉(zhuǎn)換,例如5=="5"返回true,而===要求值和類型都相同才會(huì)返回true,例如5==="5"返回false。使用場(chǎng)景上,===更安全應(yīng)優(yōu)先使用,==僅在需要類型轉(zhuǎn)換時(shí)使用。

如何在PHP( - , *, /,%)中執(zhí)行算術(shù)操作? 如何在PHP( - , *, /,%)中執(zhí)行算術(shù)操作? Jun 19, 2025 pm 05:13 PM

PHP中使用基本數(shù)學(xué)運(yùn)算的方法如下:1.加法用 號(hào),支持整數(shù)和浮點(diǎn)數(shù),也可用於變量,字符串?dāng)?shù)字會(huì)自動(dòng)轉(zhuǎn)換但不推薦依賴;2.減法用-號(hào),變量同理,類型轉(zhuǎn)換同樣適用;3.乘法用*號(hào),適用於數(shù)字及類似字符串;4.除法用/號(hào),需避免除以零,並註意結(jié)果可能是浮點(diǎn)數(shù);5.取模用%號(hào),可用於判斷奇偶數(shù),處理負(fù)數(shù)時(shí)餘數(shù)符號(hào)與被除數(shù)一致。正確使用這些運(yùn)算符的關(guān)鍵在於確保數(shù)據(jù)類型清晰並處理好邊界情況。

See all articles