eftec / apiassembler

快速API生成器

1.3 2023-03-04 13:25 UTC

This package is auto-updated.

Last update: 2024-09-04 16:45:13 UTC


README

如果您有一个正在运行的数据库,那么您可以在3分钟或更短的时间内创建一个API。这个库基于数据库的表创建一个API Rest服务器的模板。与其他库不同,这个库生成本地代码,因此允许任何定制。

它是Firebase的一个替代品,尽管它不那么友好,但它也更灵活(您可以使用您当前的数据)。

此库与以下数据库兼容(使用PDO组件)

  • MYSQL 7.0及以上

  • SQL SERVER 2008及以上

  • ORACLE 12c及以上

Packagist Total Downloads Maintenance composer php php CocoaPods

功能

  • 代码采用MVC风格。
  • (可选)自定义认证
  • 用于访问数据库的仓库类
    • 创建方法
    • 插入方法
    • 更新方法
    • 删除方法
    • 列出所有元素方法
    • 列出分页元素方法
    • 计数方法
    • 列出原始(您可以使用自己的SQL查询)方法
  • (可选)缓存
  • 基于CLI

架构理念。

此库在设计上不是RESTful的,但是您可以自定义并用作RESTful。

为什么?虽然RESTful可能很简单,但它也有限制。这个库允许创建数十个API操作,而这些操作在一个简单的RESTful服务器中是不允许的。例如,您可以使用任何动词读取信息,包括POST,为什么不呢?

允许的动词:GET、POST、PUT和DELETE。

此外,此库设计为静态的,任何操作都旨在执行简单任务,而不是具有同时执行许多操作的API方法。这与GraphQL和其他库不同,客户端可以自定义其查询。背后的原因是安全和性能。

假设我们有一个列出所有产品的新的路径。

url: domain.dom/api/Product/listall (GET/POST/PUT或DELETE)

它将分为

  • Product = 控制器。它被转换为ProductAPIController
  • listall = 动作。它被转换为listAllAction方法(添加后缀Action是为了避免客户调用其他函数)

它可以调用以下方法

// note: this class controller is generated by the CLI.
class ProductAPIController {
    // ...
    public function listAllAction($id=null,$idparent=null,$event=null) {
        // the code goes here
    }
    // ...
}

但如果我们只想为特定的动词(POST)调用它呢

class ProductAPIController {
    // ...
    public function listAllActionPOST($id=null,$idparent=null,$event=null) {
        // Check how the method ends with POST.
    }
    // ...
}

现在,假设我们只想列出“类别”中的产品,并且只为GET

url: domain.dom/api/Product/listByCategory/200 (GET)

class ProductAPIController {
    // ...
    public function listByCategoryActionGET($id=null,$idparent=null,$event=null) {
		// the $id argument contains the value 200.
    }
    // ...
}

入门指南

可以使用CLI命令生成控制器和仓库类的代码

php apisssembler createapi --interactive --loadconfig config.json
  • createapi 开始创建代码
  • --interactive 进入交互模式。您也可以通过参数输入此信息。
  • --loadconfig <filename> 允许加载以前的配置。

1) 运行代码

但是,对于初学者,只需使用此行:(因为我们还没有配置)

php apisssembler createapi --interactive

CLI会询问一些问题,例如连接到数据库等。

cli 1

如果信息正确,则会显示[OK]消息。否则,您可以再试一次。

cli 2

一旦连接,它将显示下一个菜单

cli 3

2) 扫描(必需步骤)

扫描将读取数据库以查找更改,并检测是否有新的表/列或某些表/列需要删除。

cli 3

3) 文件夹(必需步骤)

现在尝试下一个选项 folder,您可以在其中设置仓库文件将生成的地方。您还可以设置新仓库类的后缀(通常称为Repo)

您还必须设置这些类的命名空间。命名空间取决于您的文件夹结构和composer的自动完成配置。

cli 3

在这种情况下,根文件夹位于d:\www\currentproject\ApiAssembler,composer.json包含以下行

"autoload-dev": {
  "psr-4": {
    "api\\": ""
  }
}
  • if (folder) d:\www\currentproject\ApiAssembler = (namespace) api

  • then (folder) d:\www\currentproject\ApiAssembler\examples\local\repo = (namespace) api\examples\local\repo

4) Apifolder(必要步骤)

它与文件夹类似,但用于确定API控制器将位于何处以及命名空间。

cli api folder

5) 路由器(必要)

在此菜单中,您可以生成router.php、router_auth.php和.htaccess文件。

  • 您需要为每个新配置重新生成路由器类。
  • 您只需生成一次.htaccess文件。
  • router_auth.php只生成一次,因此您可以放心地编辑文件。如果想要重新生成,请删除文件。

cli 3

6) APIMethod(必要)

您可以添加或删除API控制器类的函数。

您可以单独为每个类或同时为所有类添加或删除函数。

cli api method 1

  • 函数类型决定了将生成哪种类型的函数(例如,插入、更新等)
  • 您还可以设置缓存的有效期。此功能仅在已配置缓存时生效。默认情况下,缓存未启用。
  • 依赖项表示您是否要包含另一列的值。例如,如果表有MANYTOONE关系,则可以包含这些关系的值。依赖项以"\_ColumnName"的形式编写

7) Generateapi(必要)

当您拥有所有信息时,您可以生成存储库和API控制器文件。

cli generate api

在最后一个例子中,生成了类但没有分配方法。否则,它将构建代码。

8) Saveapi(推荐)

最后,您可以保存您的配置,以便您可以运行一次。

cli 3

您可以将配置和脚本文件保存下来以再次调用此过程。

在最后一个例子中,您可以在下一行继续配置运行

./example.bat # windows
./example.sh  # linux/macos
php apisssembler createapi --loadconfig example --interactive # windows/linux/macos

为什么配置保存为PHP文件?(example.config.php)

这是出于安全考虑。该文件在网络上不可见,即使它保存在网页文件夹中。这是因为它包含一行,防止代码执行。

9) 运行代码

您可以通过打开创建文件的URL来运行代码。如果您在开发机器上,则将显示下一个屏幕。如果您点击这些选项,则可以调用您的代码,如果该功能允许方法GET并且不需要其他值。

cli run

10) 使用详细信息重命名(可选)

虽然之前的代码可以工作,但有一些命名问题。发票表被命名为"Invoic"而不是"Invoice"。此外,Invoicedetails表被称为"Invoicedetail"而不是"InvoiceDetail"。

因此,让我们重命名列

cli rename

然后,您可以重新构建路由器(菜单“router”)并再次生成文件(菜单“generateapi”)

项目结构

项目相当简约,它由3个文件夹组成

📁 根文件夹

📁 存储库文件夹

📁 API控制器文件夹

在根文件夹中有3个文件

  • .htaccess
    • (由Apache Web服务器使用)。此文件可以通过菜单选项"router"生成
  • router.php
    • 我们的en-router(用于重定向和协调调用哪个控制器以及执行。
    • 它还包括配置、实例创建等主要代码。此文件可以通过菜单中的选项 "路由器" 生成。
  • router_auth.php
    • 这是认证文件。它仅通过菜单中的选项 "路由器" 生成一次。
    • 如果要重新生成,请先删除它。
    • 您可以编辑此文件并添加自己的逻辑。
1) Select the value of databasetype [mysql] mysql/sqlsrv/oci:
2) Select the value of server [127.0.0.1] :
3) Select the value of user [root] :
4) Select the value of password [abc.123] :
5) Select the value of database [api-assembler] :

Database connected correctly

6) Select the base namespace [examples\localhost] :
7) Select the repository folder [repofolder] :repo
8) Select the api folder [apifolder] :api

Tables:

[*][1] productcategories
[*][2] products
[*][3] users
        [a] select all, [n] select none, [] end selection, [*] (is marked as selected)
9) Select or de-select a table to process [] :

Classes:

[1] Table:productcategories -> class:ProductCategory
        examples\localhost\repo\ProductCategoryRepo
        examples\localhost\api\ProductCategoryApiController
[2] Table:products -> class:Product
        examples\localhost\repo\ProductRepo
        examples\localhost\api\ProductApiController
[3] Table:users -> class:User
        examples\localhost\repo\UserRepo
        examples\localhost\api\UserApiController
10) Select the class to rename (empty to continue) [] 1-3:

Methods:

[1] examples\localhost\api\ProductCategoryApiController
         method name:custom type:empty verb:ALL
[2] examples\localhost\api\ProductApiController
         method name:custom type:empty verb:ALL
[3] examples\localhost\api\UserApiController
         method name:insert type:insert verb:ALL
[4] All Classes
11) Select the class you want to add a new method (empty to continue) [] 1-4:
12) Do you want to generate the route file? [yes] yes/no:
13) Is it a developer or production machine? [dev] dev/prod:
14) Set your machine name [PCJC] :
15) Select the base url (dev) [http://localhost] :
16) Select the base url (prod) [http://localhost] :
17) Select the folder url [api] :
18) Do you want to use cache? [no] yes/no:yes
   1) Is it a developer or production machine? [redis] redis/apcu/memcached:
   2) Cache server [127.0.0.1] :
   3) Cache port [6379] :
   4) Cache schema [] :
   5) Cache user [] :
   6) Cache password [] :
19) Do you want to override the files with the classes? [no] yes/no:yes

Errors found:

Folder:
Folder:
router.php saved correctly

20) do you want to save the configuration? Note: it includes the database password [yes] yes/no:yes
select the filename [file2.json] :
File saved correctly
Done.
  1. 选择数据库类型,mysql、sqlsrv(mssql服务器)或oci(Oracle)
  2. 选择服务器机器。它取决于数据库类型
    1. mysql:服务器的IP
    2. sqlsrv:IP/实例或机器/实例名称
    3. oci:可以是tsname或ez-config
  3. 数据库的用户名。在OCI中,它也是模式。
  4. 数据库的密码。
  5. 要连接的数据库。
  6. 基本命名空间,例如:"\namespace1\namespace2"
  7. 将生成仓库类的文件夹(相对于当前路径)。
    1. 如果文件夹不存在,则将其创建。
  8. 将生成apiclasses的文件夹(相对于当前路径)。
    1. 如果文件夹不存在,则将其创建。
  9. 可以选择要处理或删除的表。所有标记有"*"的表都被选中
  10. 您可以选择重命名一个类。
    1. 默认情况下,类的名称使用单数表名生成。
  11. 您可以向类添加方法
    1. 在此方法中,您可以为一个类添加一个新方法。一个方法由方法类型、名称和HTTP动词组成。查看方法列表以获取更多信息。
  12. 如果希望生成路由文件(route.php)。如果文件存在且选择“不覆盖”,则不生成文件,并且:您可以手动删除它或强制覆盖它。
  13. 您可以选择当前机器是开发机还是生产机。Router.php默认包含两个环境,开发环境和产品环境。代码会自动使用机器名称确定当前环境。
  14. 您可以设置机器名称或自动设置。
  15. 您可以设置基本Web URL(开发者)。基本Web是必须在当前文件夹中显示的Web。
    1. 例如,假设您正在新文件夹 /var/www/domain.dom/example/folder 或文件夹 c:\www\example\folder 中工作,那么如果根URL文件夹(http://localhost)指向 /var/www/domain.domc:\www,那么您的基Web URL必须是 http://localhost/example/folder(不带尾随"/")
  16. 您可以设置基本Web URL(生产)。基本Web是必须在当前文件夹中显示的Web。
  17. 您可以设置API文件夹。
    1. 端点URL由 **BASE WEB URL / API FOLDER / 控制器 / 动作 / ID / IDPARENT ** 组成
    2. 示例:"http://localhost/api/Product/list/20"(在这个例子中,idparent未设置)
  18. 您可以选择是否使用缓存或不使用缓存。
    1. 您可以选择缓存类型(redis、apcu或memcached)
    2. 您可以选择缓存服务器的IP(通常是127.0.0.1)
    3. 您可以选择缓存服务器的端口号
    4. 您可以选择缓存的模式(或文件夹)
    5. 如果您有的话,可以选择缓存服务器的用户
    6. 如果您有的话,可以选择缓存服务器的密码
  19. 如果您标记为是,则所有文件都将被覆盖。否则,代码只生成不存在的文件。
  20. 最后,您可以将所有用户输入值保存到文件中。
    1. 以后,您可以恢复配置为 php ApiAssembler.php -create -file file.json

方法列表

这是允许创建新方法的模板方法列表。

动词

数据库方法

此库使用EFTEC/PDOOne来连接数据库。

$identity=RepoClass::insert($obj); // (DML) insert a record 
$result=RepoClass::update($obj); // (DML) update a record
$result=RepoClass::deleteById($primarykey); // (DML) delete a record by the primary key
$result=RepoClass::deleteById($obj); // (DML) delete a record by the object.
$result=RepoClass::toList(); // list all values
$result=RepoClass::first(); // returns only the first row (if any)
$result=RepoClass::where('condition',[param])->toList(); // a "where" condition.
$result=RepoClass::order('column')->toList(); // sort the values by a column
$result=RepoClass::count(); // returns the number of rows.
$result=RepoClass::where('condition',[param])->count(); // returns the number of rows with conditions
$result=RepoClass::setRecursive('_column')->toList(); // if Repo Class contains a relational column (Many to One, One To Many, etc.), then this field is returned. By default all columns that could be recursive starts with "_".
$result=RepoClass::query('select * from table where id=?',[param]); // execute a raw query with or without parameters.

还有许多其他方法(包括DDL方法),但这些都是基本方法。

缓存

它还允许按如下方式缓存结果

$result=RepoClass::useCache(5000)->toList(); 
// the result is cached for 5000 seconds. Passed 5000 seconds, the cache is destroyed.
// the cache is also destroyed if we run any DML command, such as insert,update or delete using the same Repo Class
// the cache could also be invalidated manually:
$result=RepoClass::invalidateCache('cachespecial');
// However, the cache is not destroyed if we run a DML command via query, of if we update a value using another repository class.

// You can set the group/family of cache as follows:
$result=RepoClass::useCache(5000,'cachespecial')->toList(); 
//and you can invalidate with
$result=RepoClass::invalidateCache('cachespecial');

读取信息

如果您想读取用户输入,那么您仍然可以使用$_GET和$_POST值,但也可以从路由器读取值

读取正文

$values=$this->api->routeOne->getBody(true); // it reads the body and de-serialize the json as an associative array.

读取头部

$value=$this->api->routeOne->getHeader('key','default value if not found');

读取URL参数

$value=$this->api->routeOne->getParam('key','default value if not found');

读取POST参数

$value=$this->api->routeOne->getPost('key','default value if not found');

如果没有URL参数,则读取POST

$value=$this->api->routeOne->getRequest('key','default value if not found');

变更日志

  • 1.3 2023-03-04

    • 添加了composer中的bin。
  • 1.2 2023-03-04

    • 代码更新。
  • 1.0 2022-09-01

    • 首次发布版本
  • 0.2 2022-03-06

    • 生成脚本
    • 生成API控制器
    • 正确保存脚本
    • 交互式
    • 非交互式
    • 保存文件
  • 0.1 首个版本

许可证

版权:Jorge Castro Castillo - Eftec Chile (2022-203)

双重许可证,GPL-v3和商业。请参阅许可证文件以获取更多信息

简而言之(非法律建议)

"您可以在跟踪源文件中的更改/日期的情况下复制、分发和修改软件。对或包含(通过编译器)GPL许可证代码的任何修改都必须在GPL下提供,并附带构建和安装说明。如果您不想使用GPL许可证,则可以选择商业许可证。"