使用系统接口

所有的DreamFactory版本都包含一个基于web的管理控制台,用于管理平台的各个方面。虽然此控制台为执行诸如管理api、管理员和业务逻辑等任务提供了用户友好的解决方案,但许多公司希望通过脚本实现自动化管理。这样做有两个值得注意的原因:

  • 多环境管理:在将api部署到生产环境之前,应该始终在各种测试和QA环境中进行严格的测试。万博max手机网页登录虽然DreamFactory确实提供了服务导出/导入机制,但编写能够自动化多环境服务创建的自定义脚本通常要方便得多。
  • 与第三方服务集成:由于能够将DreamFactory集成到解决方案中,与创建新的SaaS产品(如API货币化)相关的复杂性可以大大降低。万博max手机网页登录支付之后,SaaS可以与DreamFactory交互,生成新的基于角色的访问控制、API密钥,并定义容量限制。然后可以将新的API密钥呈现给订阅者。

在本章中,我们将通过几个例子来解释这两个用例是如何实现的。

创建数据库API

要创建数据库API,您将发送一个帖子/ api / v2 /系统/服务端点。请求有效负载将包含所有API配置属性。例如,这个有效负载反映了创建MySQL API所需的内容:

{"resource":[{"id":null, "name":"mysql", "label":" mysql API", "description":" mysql API", "is_active":true, "type":"mysql", "config":{"max_records":1000, "host":"HOSTNAME", "port":3306, "database":" database", "username":" username", "password":" password"}, "service_doc_by_service_id":null}]}

在提交成功的请求之后,一个201年创建状态码与新创建的服务ID一起返回:

{"resource": [{"id": 194}]}

检索服务类型和配置模式

每种服务类型自然都需要不同的配置模式。例如,大多数数据库服务类型要求提供主机名、用户名和密码,而AWS S3服务类型要求提供AWS访问密钥ID、秘密访问密钥和AWS区域。您可以通过发出命令来获得受支持的服务类型和相关配置模式的列表得到请求/ api / v2 /系统/ service_type.这将返回一个相当长的响应,其中包含名称和配置模式,其中的一小部分将在这里重新创建:

{"resource": [{"name": "adldap", "label": "Active Directory", "description": "支持Active Directory集成的服务","group": "LDAP", "singleton": false, "dependencies_required": null, "subscription_required": "SILVER", "service_definition_editable": false, "config_schema": [{"alias": null, "name": "host", "label": "host", "description": " AD/LDAP服务器的主机名","native": [], "type": "string", "length": 255,…}]}]}

如果您只想检索服务类型名称的列表,则发出相同的命令得到请求,但带有=字段名称附加参数:

/ api / v2 /系统/ service_type吗?=字段名称

这将返回一个服务类型名称列表:

{“资源”:[{“名称”:“adldap”},{“名称”:“amqp”},{“名称”:“导引”},…{" name ": "用户"},{"名称":“v8js”},{“名称”:“webdav_file”}]}

检索API详细信息

要检索关于特定API的配置详细信息,可以发出得到请求/ api / v2 /系统/服务.您可以传递API ID或API名称(命名空间)。例如,通过ID检索服务配置,你将像这样传递ID:

/ api / v2 /系统/服务/ 8

通过API的名称空间引用API可能更自然。方法传递名称过滤器参数:

/ api / v2 /系统/服务?过滤器= name = mysql

在这两种情况下,响应将是这样的:

{"resource": [{"id": 8, "name": "mysql", "label": "mysql API", "is_active": true, "type": "mysql", "mutable": true, "deletable": true, "created_date": "2019-02-27 02:14:17", "last_modified_date": "2019-08-20 20:40:15", "created_by_id": "1", "last_modified_by_id": "3", "config": {"service_id": 8, "options": null, "attributes": null, "statements": null, "host": " databe.dreamfactory.com ", "port": 3306, "database": "employees", "username": "demo", "password":"**********", "schema": null, "charset": null, "collation": null, "timezone": null, "modes": null, "strict": null, "unix_socket": null, "max_records": 1000, "allow_upsert": false, "cache_enabled": false, "cache_ttl": 0}}]}

创建脚本API部署解决方案

现在,您已经了解了如何创建和查询dreamfactory管理的api,您的大脑可能正在思考所有可以自动化管理任务的方法。实际上,有许多不同的方法可以实现这一点,因为所有现代编程语言都支持执行HTTP请求的能力。实际上,您可以考虑创建一个执行的简单shell脚本旋度命令。首先创建一个包含服务创建请求有效负载的JSON文件:

{"resource":[{"id":null, "name":"mysqltest09032019", "label":"mysql test", "description":"mysql test", "is_active":true, "type":"mysql", "config":{"max_records":1000, "host":"HOSTNAME", "port":3306, "database":" database", "username":" username", "password":" password"}, "service_doc_by_service_id":null}]}

命名此文件mysql-万博max手机网页登录production.json,不要忘记更新身份验证占位符。接下来,创建一个包含以下代码的shell脚本:

# !curl -d @mysql-production万博max手机网页登录\ -H "Content-Type: application/json" \ -H "X-DreamFactory-Api-Key: YOUR_API_KEY" \ -X POST https://YOUR_DOMAIN_HERE/api/v2/system/service

将此脚本另存为create-service.sh然后更新权限,使其在运行之前可执行:

$ chmod u+x create-service.sh $ ./create-service.sh {"resource":[{"id":196}]}

当然,这是一个非常简单的示例,可以快速构建一个更健壮的解决方案。例如,你可以创建几个JSON文件,一个用于开发、测试和生产,然后修改脚本以允许环境参数:万博max手机网页登录

$ ./create-service.sh生万博max手机网页登录产

创建脚本服务来执行批量操作

有一个很有用的DreamFactory特性,允许管理员将数据库函数添加到列中,这样当API检索该列时,该函数将在其位置运行。例如,假设你想要改变日期字段的格式,你可以使用ORACLE的TO_DATE()函数来做到这一点:

TO_DATE({value}, 'DD-MON-YY HH.MI.SS AM')

DreamFactory可以通过将TO_DATE({value}, ' DD-MON-YY HH.MI.SS AM ')添加到字段的DB函数使用设置中来配置,该设置可以通过进入Schema选项卡,选择一个数据库,然后选择一个表来找到。然后单击fields部分中的一个字段。

要在服务级别执行此操作,我们可以通过转到Services -> script ->并选择您所选择的语言来创建脚本服务。我们将选择PHP。下面的脚本将数据库函数添加到所有列中,并允许我们将其作为Bulk Action执行。

$api = $平台['api'];$get = $api->get;$patch = $api->补丁;$options = [];set_time_limit (800000);//获取所有表的URL。用你的API命名空间$url = '/_table';//调用父API $result = $get($url);$fieldCount = 0;$tableCount = 0; $tablesNumber = 0; // Check status code if ($result['status_code'] == 200) { // If parent API call returns 200, call a MySQL API $tablesNumber = count($result['content']['resource']); // The next line is to limit number of tables to first 5 to see the successfull run of the script //$result['content']['resource'] = array_slice($result['content']['resource'], 0, 5, true); foreach ($result['content']['resource'] as $table) { // Get all fields URL $url = "/_schema/" . $table['name'] . "?refresh=true"; $result = $get($url); if ($result['status_code'] == 200) { $tableCount++; foreach ($result['content']['field'] as $field) { if (strpos($field['db_type'], 'date') !== false || strpos($field['db_type'], 'Date') !== false || strpos($field['db_type'], 'DATE') !== false) { // Patch field URL $fieldCount++; $url = "/_schema/" . $table['name'] . "/_field"; // Skip fields that already have the function if ($field['db_function'][0]['function'] === "TO_DATE({value}, 'DD-MON-YY HH.MI.SS AM')") continue; // Remove broken function $field['db_function'] = null; $payload = ['resource' => [$field]]; $result = $patch($url, $payload); // Add correct function $field['db_function'] = [['function' => "TO_DATE({value}, 'DD-MON-YY HH.MI.SS AM')", "use" => ["INSERT", "UPDATE"]]]; $payload = ['resource' => [$field]]; $result = $patch($url, $payload); if ($result['status_code'] == 200) { echo("Function successfully added to " . $field['label'] . " field in " . $table['name'] . " table \n"); \Log::debug("Function successfully added to " . $field['label'] . " field in " . $table['name'] . " table"); } else { $event['response'] = [ 'status_code' => 500, 'content' => [ 'success' => false, 'message' => "Could not add function to " . $field['label'] . " in " . $table['name'] . " table;" ] ]; } } } \Log::debug("SCRIPT DEBUG: Total tables number " . $tablesNumber . " -> Tables " . $tableCount . " fieldCount " . $fieldCount); } else { $event['response'] = [ 'status_code' => 500, 'content' => [ 'success' => false, 'message' => "Could not get all fields." ] ]; } } } else { $event['response'] = [ 'status_code' => 500, 'content' => [ 'success' => false, 'message' => "Could not get list of tables." ] ]; } return "Script finished";

调用服务

从任何REST客户端发出请求GET /api/v2/apinamespace,您应该会得到一个状态200。一个简单的REST客户端可以在/test_rest.html中找到。请记住,如果您不是管理用户,您的用户角色必须允许访问自定义脚本服务。

清除DreamFactory服务缓存

出于性能考虑,DreamFactory缓存所有服务定义,这样就不必从系统数据库中重复读取配置。因此,在编辑服务时,您需要随后清除服务缓存,以便您的更改生效。若要清除特定服务的缓存,发出命令删除请求到下面的URI,并将服务ID附加到它:

/ api / v2 /系统/管理/会议/ 8

清除缓存所有已定义的服务,发出一个删除请求到以下URI:

/ api / v2 /系统/管理/会话

管理角色

创建API之后,通常需要生成基于角色的访问控制和API密钥。基于api的角色管理有点复杂,因为它涉及到位掩码。位掩码的定义如下:

动词 面具
得到 1
帖子 2
4
补丁 8
删除 16

要创建角色,您将发送一个帖子请求/ api / v2 /系统/角色,并附有如下的有效载荷:

{"resource":[{"name": "MySQL Role", "description": "MySQL Role", "is_active": true, "role_service_access_by_role_id": [{"service_id": service_id, "component": "_table/employees/*", " verver_mask ": 1, "requestor_mask": 3, "filters": [], "filter_op": "AND"}, {"service_id": service_id, "component": "_table/supplies/*", " verver_mask ": 1, "requestor_mask": 3, "filters": [], "filter_op": "AND"}], "user_to_app_to_role_by_role_id": []}]}

这个有效负载为角色分配了两个权限:

  • 它可以发送得到_table /员工/ *与标识的API相关联的端点SERVICE_ID
  • 它可以发送得到而且帖子_table /供应/ *与标识的API相关联的端点SERVICE_ID

在这两种情况下,verb_mask设置为3.,因为您将一起添加权限掩码以实现所需的权限级别。例如得到(1) +岗位23..如果要允许所有动词,则需要将所有掩码加在一起1+2+4+8+1631.的requestor_mask设置为3.因为就像verb_mask它由位掩码表示。的值1表示API访问,而2表示使用DreamFactory脚本语法的访问。因此,值为3.确保端点可以通过API端点和脚本环境访问。

您可以了解更多关于角色管理的信息在我们的维基

查看角色权限

查询角色的基本信息/ /系统/作用端点并传递角色的ID。例如,检索与ID关联的角色的信息137你将查询这个端点:

/ api / v2 /系统/角色/ 137

这将返回以下信息:

{"id": 137, "name": "Dashboard Application Role", "description": "Dashboard Application Role", "is_active": true, "created_date": "2020-04-06 17:56:00", "last_modified_date": "2020-04-06 18:10:31", "created_by_id": "1", "last_modified_by_id": "1"}

但是,您通常希望了解更多关于角色的信息,包括已经分配了哪些权限。要做到这一点,你需要加入role_service_access_by_role_id字段:

/ api / v2 /系统/角色/ 137 ?相关的=role_service_access_by_role_id

这将返回包含已分配权限的详细有效负载,包括每个权限的服务标识符、端点、谓词掩码、请求者掩码和任何行级过滤器(如果适用):

{"id": 137, "name": "Dashboard应用角色","description": "Dashboard应用角色","is_active": true, "created_date": "2020-04-06 17:56:00", "last_modified_date": "2020-04-06 18:10:31", "created_by_id": "1", "last_modified_by_id": "1", "role_service_access_by_role_id": " {"id": 168, "role_id": 137, "service_id": 25, "component": "_table/customer/*", " verver_mask ": 1, "requestor_mask": 1, "filters": [], "filter_op": "AND", "created_date": "2020-04-06 17:56:00", "last_modified_date": "2020-04-06 17:56:00":"2020-04-06 17:56:00", "created_by_id": null, "last_modified_by_id": null}, {"id": 184, "role_id": 137, "service_id": 145, "component": "_table/account/*", " verver_mask ": 1, "requestor_mask": 1, "filters": [], "filter_op": "AND", "created_date": "2020-04-07 14:39:38", "last_modified_date": "2020-04-07 14:39:38", "created_by_id": null, "last_modified_by_id": null}]}

更新已有角色

要添加对现有角色的权限,您将在role_services_access_by_role_idJSON对象。例如,为按ID标识的角色添加新的权限137你将发送一个PUT请求到这个端点:

/ api / v2 /系统/角色/ 137

最小的JSON有效负载如下所示:

{" id ": 137,“role_service_access_by_role_id”:[{“service_id”:25岁的“组件”:“_table /客户/ *”、“verb_mask”:1、“requestor_mask”:1、“过滤器”:[],“filter_op”:“和“}]}

要从现有角色删除现有权限,需要设置role_id

{" id ": 137,“role_service_access_by_role_id”:[{" id ": 168年,“role_id”:零}]}

管理API密钥

可以通过系统API创建和管理API密钥。检索所有API键的列表(称为应用程序用梦工厂的行话来说),发送一个得到请求到URI/ api / v2 /系统/应用程序.你会收到一个应用程序列表,看起来像这样:

{"id": 5, "name": "weatherappapi", "api_key": "api_key", "description": "weatherappapi", "is_active": true, "type": 0, "path": null, "url": null, "storage_service_id": null, "storage_container": null, "requires_fullscreen": false, "allow_fullscreen_toggle": true, "toggle_location": "top", "role_id": 2, "created_date": "2019-02-28 17:55:29", "last_modified_date": "3", "last_modified_by_id": null, "launch_url": "},

方法标识所需的字段,以检索应用程序名称和相关的API键字段参数:

/ api / v2 /系统/应用程序?=字段名称,api_key

下面是一个例子。注意launch_url属性总是返回:

{“资源”:[{“名称”:“weatherappapi”,“api_key”:“api_key”、“launch_url ": "" }, { " 名称”:“HR应用程序”、“api_key”:“api_key”、“launch_url ": "" }, { " 名称”:“MySQL”、“api_key”:“api_key”、“launch_url ": "" } ] }

属性返回每个应用程序定义的角色相关的参数。发出一个得到请求到以下URI:

/ api / v2 /系统/应用程序?相关的=role_by_role_id

这将返回一个应用程序列表,以及与该应用程序关联的任何角色。注意在下面的示例中,一个嵌套的JSON对象名为role_by_role_id包括角色定义:

{"id": 5, "name": "天气应用API", "api_key": "api_key", "description": "天气应用API", "is_active": true, "type": 0, "path": null, "url": null, "storage_service_id": null, "storage_container": null, "requires_fullscreen": false, "allow_fullscreen_toggle": true, "toggle_location": "top", "role_id": 2, "created_date": "2019-02-28 17:55:29", "last_modified_date": "3", "last_modified_by_id": null, "launch_url": "" role_by_role_id": "{"id": 2, "name": "Weather App API Role", "description": "Role for Weather App API", "is_active": true, "created_date": "2019-02-28 17:54:56", "last_modified_date": "2019-02-28 17:54:56", "created_by_id": "3", "last_modified_by_id": null}}
Baidu
map