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。

此外,此库按设计是静态的,任何动作都旨在执行简单的任务,而不是同时执行许多操作。这与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) API文件夹(必需步骤)

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

cli api folder

5) 路由器(必需)

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

  • 您需要为每个新的配置重新生成路由器类。
  • 您只需要生成一次.htaccess文件。
  • router_auth.php只生成一次,因此您可以放心编辑文件而不用担心它会被覆盖。如果您想重新生成,则删除该文件。

cli 3

6) API方法(必需)

您可以添加或删除API控制器类的方法。

您可以为一类或同时为所有类添加或删除方法。

cli api method 1

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

7) 生成API(必需)

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

cli generate api

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

8) 保存API(推荐)

最后,您可以保存您的配置,这样您就可以运行它一次。

cli 3

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

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

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

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

这是出于安全考虑。该文件通过互联网不可见,即使它位于Web文件夹中。这是因为它包含一行代码,可以避免代码执行。

9) 运行代码

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

cli run

10) 使用详细资料重命名(可选)

尽管前面的代码可以工作,但存在一些命名问题。Invoices表被命名为"Invoic"而不是"Invoice"。同样,Invoicedetails表被命名为"Invoicedetail"而不是"InvoiceDetail"。

所以让我们重命名列

cli rename

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

项目结构

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

📁 根目录

📁 存储库文件夹

📁 API控制器文件夹

在根目录中有3个文件

  • .htaccess
    • (由Apache Web服务器使用)。此文件可以通过菜单选项 "路由器" 生成
  • router.php
    • 我们的路由器(负责重定向和协调调用哪个控制器并执行)。
    • 这是包含配置、实例创建等主要代码的文件。此文件可以通过菜单选项"路由器"生成。
  • 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由**基本Web URL / API文件夹 / 控制器 / 动作 / 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许可证,则可以选择商业许可证。"