允许您使用PHP类来表示API端点来创建REST API。

2.0.1 2021-06-06 22:14 UTC

This package is not auto-updated.

Last update: 2024-09-23 14:33:55 UTC


README

允许您使用PHP类来表示API端点来创建REST API。

安装

在您的计算机上安装并初始化了Composer的项目后,在项目的根目录中运行此命令

composer require lamansky/api

需要PHP 7.4或更高版本。

使用教程

简介

端点是能够接收REST命令的URL(或URL模式)。您的API中的每个端点都将由一个PHP类表示。这个PHP类实现了适用于它所能接收的REST命令的适当的Endpoint接口。

每个REST命令都被实现为端点控制器的一个公共方法

<?php
use Lamansky\Api\ReadOnlyEndpoint;
use Lamansky\Api\Responder;

class HelloWorldEndpoint implements ReadOnlyEndpoint {
    public function getRoutePattern() : string {
        return '/hello-world/';
    }

    public function get() : Responder {
        return new Responder(Responder::OK, 'text/plain', 'Hello world!');
    }
}

每个REST方法返回一个Responder对象。(Responder类还有几个子类供您使用,例如JsonResponderFileResponderDeferredResponder。)

一旦您的端点就绪,请将它们添加到API对象中

<?php
use Lamansky\Api\Api;

$api = new Api('/api');
$api->registerEndpoint(new HelloWorldEndpoint());
$api->getResponder()->sendResponseAndDie();

您还需要确保服务器将所有请求路由到上述文件。假设此文件名为index.php,并且您正在运行Apache,则可以创建一个类似下面的.htaccess文件

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]

现在您有一个可用的API!如果您的站点正在运行在localhost上,那么当您向https:///api/hello-world/发送GET命令时,API将输出Hello world!

URL变量

到目前为止,我们已经看到了如何创建一个具有静态URL的端点。但如果我们需要操作一个具有给定ID的项目怎么办呢?

<?php
use Lamansky\Api\ItemEndpoint;
use Lamansky\Api\Responder;

class ExampleItemEndpoint implements ItemEndpoint {
    public function getRoutePattern() : string {
        return '/example-item/[i:id]/';
    }

    public function get(int $id=null) : Responder {
        return new Responder(Responder::OK, 'text/plain', (string)$id);
    }

    public function put(int $id=null) : Responder {
        return new Responder(Responder::NOT_IMPLEMENTED);
    }

    public function delete(int $id=null) : Responder {
        return new Responder(Responder::NOT_IMPLEMENTED);
    }
}

在我们的路由模式字符串中,我们添加了一个名为id的处理器。然后它自动映射到我们的REST动词方法中的$id变量。

Lamansky/Api库使用AltoRouter来处理路由映射。有关[i:id]语法的更多信息,请参阅该库的路由映射文档

GET/POST变量

通过JSON POST请求或通过GET查询字符串变量发送的任何变量都作为变量自动可访问。

public function post(string $title=null, string $content=null, id $category_id=null) : Responder {
    // Save item and return a Responder
}

请注意,$category_id参数遵循PHP的带下划线的变量命名约定。然而,JSON通常使用驼峰式键,GET变量通常是小写的。这不是问题:库将在POST/GET中查找categoryIdcategoryid,并将其自动映射到$category_id变量。

JSON视图

如果您正在构建JSON API,请考虑使用JsonView类将模型转换为JSON

<?php
use Lamansky\Api\CollectionEndpoint;
use Lamansky\Api\ItemEndpoint;
use Lamansky\Api\Responder;
use Lamansky\Api\JsonView;

class BlogPostJsonView extends JsonView {
    public function render($blog_post) : array {
        return ['id' => $blog_post->id, 'title' => $blog_post->title, 'content' => $blog_post->content];
    }
}

class BlogPostItemEndpoint implements ItemEndpoint {
    public function getRoutePattern() : string {
        return '/post/[i:id]/';
    }

    public function get(int $id=null) : Responder {
        // TODO: Use the ID to get the BlogPost object from your database
        return (new BlogPostJsonView())->single($blog_post);
    }

    public function put(int $id=null) : Responder { return new Responder(Responder::NOT_IMPLEMENTED); }
    public function delete(int $id=null) : Responder { return new Responder(Responder::NOT_IMPLEMENTED); }
}

class BlogPostCollectionEndpoint implements CollectionEndpoint {
    public function getRoutePattern() : string {
        return '/post/';
    }

    public function get() : Responder {
        // TODO: Get all the BlogPost objects in an array
        return (new BlogPostJsonView())->multiple($blog_posts);
    }

    public function post(int $id=null) : Responder { return new Responder(Responder::NOT_IMPLEMENTED); }
}

完整示例

<?php
use Lamansky\Api\Api;
use Lamansky\Api\ItemEndpoint;
use Lamansky\Api\Responder;
use Lamansky\Api\JsonResponder;
use Lamansky\Api\JsonView;

class TestItemEndpoint implements ItemEndpoint {
    public function getRoutePattern() : string {
        return '/test/[i:id]/';
    }

    public function get(int $id=null) : Responder {
        if ($id < 1) return new Responder(Responder::NOT_FOUND);
        $test = new Test($id);
        return (new TestJsonView())->single($test);
    }

    public function put(int $id=null) : Responder {
        return new Responder(Responder::NOT_IMPLEMENTED);
    }

    public function delete(int $id=null) : Responder {
        return new Responder(Responder::FORBIDDEN);
    }
}

class Test {
    public $id;

    public function __construct(int $id) {
        $this->id = $id;
    }
}

class TestJsonView extends JsonView {
    public function render($test) : array {
        return ['id' => $test->id];
    }
}

$api = new Api('/api');
$api->registerEndpoint(new TestItemEndpoint());
$api->getResponder()->sendResponseAndDie();

https:///api/test/1/的GET请求将生成

{
    "id": 1
}

版本迁移指南

以下是您需要了解的向后不兼容的更改。

1.x ⇒ 2.x

  • 最低支持的PHP版本现在为7.4(而不是7.1)。
  • darsyn/ip依赖项已更新到4.x版本,这可能会对依赖于Darsyn\IP\IP对象公共API的用户引入一些向后不兼容的更改,该对象以前由Client::instance()->getIp()方法返回。现在此方法返回一个包装了darsyn/ip库的Lamansky\Api\IpAddress对象,这将成为对该依赖项进一步向后不兼容更改的缓冲。如果您以前使用的是Darsyn\IP\Doctrine\IpType Doctrine2类型,请考虑用兼容包装器Lamansky\Api\Doctrine\IpAddressType替换它。