基于函数的小型框架。

v0.0.0 2021-07-06 18:53 UTC

This package is auto-updated.

Last update: 2024-09-07 21:13:07 UTC


README

概述

Corto 是一个用于构建 REST API 的微框架。这个框架的哲学是围绕使用函数、单例和静态对象调用,以替代对全局变量的依赖。这个框架不试图制作一个大型的面向对象解决方案,而是对从请求中链式调用函数有明确观点的方法。

这个框架中有两个类: RequestPipe。其余的都是函数。

Request

Request 对象是一个单例,它从全局变量 $_SERVER 中提取 URI 和 HTTP 方法,并将 php://input 转换为数组。它期望输入为 JsonSerializable

Pipe

Pipe 是一个可调用的对象,它有一个名为 $valuemixed 属性。调用对象返回一个 callable,它修改 $value 然后返回 $this。这允许在值上创建简洁的管道函数语法。

(new Pipe(10))
    (fn($x) => $x * 2);

// returns 20

函数

Corto 围绕函数工作流程构建。

  • request 用于检索请求数据。
  • route 用于监听 HTTP 请求,解析路径并返回响应。
  • response 用于设置 HTTP 状态码并返回 JSON。

request

调用 request() 返回 Request 单例。在创建函数时,使用 request()->input 来访问发送的数据。

route

route 函数是框架中最复杂的。它是一个柯里化函数,首先描述 HTTP 方法。

route('GET');

这返回一个函数,它接受两个参数:路径和回调。路径是字符串,与请求的 URI 进行比较。有两种类型的路径:文本路径变量路径

文本路径

文本路径不包含变量,并直接与 URI 进行比较。一个文本路径的例子是 /path/to/resource

route('GET')('/path/to/resource', ...);

变量路径

变量路径包含花括号来表示传递给回调函数的路径值。在比较 URI 之前,变量路径被转换为正则表达式。一个变量路径的例子是 /path/to/resource/{variable}

route('GET')('/path/to/resource/{variable}', ...);

注意 花括号之间的单词没有意义,花括号之间可以使用的任何单词都可以用来表示该值。如果变量路径中包含多个变量,它们将按照顺序传递给回调。

response

响应函数是一个柯里化函数,它从 HTTP 响应代码开始。该函数返回的调用者期望 arrayJsonSerializable 数据。它设置 HTTP 响应代码,然后将数据转换为 JSON,以 JSON 格式回显。回显完成后,它 退出

这个函数与 JSON 输出紧密耦合,并且终止程序。我对这些决定感到满意,因为框架严格定义了单一目的:根据请求交付 JSON 响应

示例

以下是如何实现 函数 部分中描述的功能的示例。这应该放在您的公共脚本中,例如 index.php

<?php declare(strict_types=1);

include __DIR__ . "/../vendor/autoload.php";

use function Rodriguezric\Corto\{route, route_chain, response, request};

set_exception_handler(
    function($exception) {
        file_put_contents("php://stderr", $exception->getMessage());

        return response(400)(['error' => 'Exception thrown.']);
    }
);

$hello = fn() => response(200)(['message' => 'Hello']);

route('GET')('/', $hello);

$create_person = function() {
    if (request()->is_missing('name')) {
        return response(400)(['error' => 'Missing arguments']);
    }

    $name = request()->input['name'];

    return response(200)(['message' => "Created new person with name {$name}"]);
};

route('POST')('/person', $create_person);

$update_person = fn($id) => response(200)(['message' => "Updated person with id: {$id}"]);

route('PUT')('/person/{id}', $update_person);

response(400)(['message' => 'Resource not found.']);

我将解释示例中的某些部分,以说明它们的目的。

异常处理

set_exception_handler(
    function($exception) {
        file_put_contents("php://stderr", $exception->getMessage());

        return response(400)(['error' => 'Exception thrown.']);
    }
);

本段代码将向请求者发送带有JSON响应的400响应。

{
    "error": "Exception thrown."
}

同时,在服务器端,它将实际异常消息发送到标准错误。我将这两个消息分开,以便我可以在容器日志中查看错误,向请求者告知发生了错误,但仍然隐藏详细信息。

请求示例

GET

$hello = fn() => response(200)(['message' => 'Hello']);

route('GET')('/', $hello);

本节设置了一个简单的GET请求,并将一个函数作为可调用对象传递。该函数返回response调用的结果。函数response回显其结果并终止脚本。

POST

$create_person = function() {
    if (request()->is_missing('name')) {
        return response(400)(['error' => 'Missing arguments']);
    }

    $name = request()->input['name'];

    return response(200)(['message' => "Created new person with name {$name}"]);
};

route('POST')('/person', $create_person);

本节设置了一个POST请求。可调用对象测试请求以确保请求中包含name字段。如果缺少该字段,它将发送400 HTTP响应代码,并带有表示错误的JSON消息。

{
    "error": "Missing arguments."
}

如果请求中包含name属性,它将使用该值创建其响应。这个例子是虚构的,因为它只显示提供名称的JSON,通常我们会在这里执行我们的工作并发送包含有用信息的响应。

PUT

$update_person = fn($id) => response(200)(['message' => "Updated person with id: {$id}"]);

route('PUT')('/person/{id}', $update_person);

在这个例子中,我们使用了PUT请求。这是第一个使用变量路径的例子。传递给路由函数的可调用对象必须有一个参数,以便使用路径中描述的变量。