API客户端的优秀架构是什么?

时间:2016-12-04 19:25:07

标签: web-services guzzle api-design

我将从头开始创建一个用于REST API的PHP客户端。我考虑使用Guzzle library

我认为用户不应该处理诸如请求对象之类的传输事务(甚至来自自定义xxxRequest类),并且应该只处理业务对象/服务类。但可能是我错了......

以下是可能的架构的一些示例。哪些方面的良好做法和原因?
随意改进它们或提出更好的方法。

示例1:

class ApiClient {
    function createBooking (BookingEntity $booking, CustomerEntity $customer) {
        //...
    }
}

此示例允许用户仅使用业务对象,但如果API需要大量方法,则ApiClient类可能开始变脏...此外,如果我们要添加功能,则必须修改ApiClient。

示例2:

class ApiClient {
    function execute(CreateBookingRequest $createBookingRequest) {
        //...
    }
}

class CreateBookingRequest {
    private BookingEntity $booking;
    private CustomerEntity $customer;
    private $queryParams;

    public createQueryParams() {
        // to create the query params (from the attibutes) for the http client
    }
}

如果需要新功能,则不需要修改ApiClient,只需要创建一个新类。但是,用户必须处理以Request后缀命名的类。 IMO他对请求或技术方面一无所知。

示例3:

class BookingService {
    function createBooking (BookingEntity $booking, CustomerEntity $customer) {
    //... 
    }
}

此示例添加一个图层。

在所有情况下,ApiClient / Service类中的Guzzle httpClient属性应该在哪里?或者ApiClient类是否应该扩展Guzzle Client类?

1 个答案:

答案 0 :(得分:1)

那么,那里没有真正的标准,但这绝对是一个热门话题,我甚至会说,这不是Guzzle特有的。

简短回答:我会根据API的复杂性在选项1和3之间进行选择。

更长的答案:如果有不同的资源(比如预订获取,创建,删除等等),那么我会选择选项3.如果只有少量的API调用,那么我仍会使用选项3 ,因为从API的角度来看它是一个更好的表示(你的API客户端实际上只是API的一个实现,所以它应该遵循API的约定,术语......至少在理论上),但选项1可能更快,起初更容易理解。如果API变得更加复杂,那么维护会变得很难,所以即使这样,最终也必须将其重写为选项3。

配置的Guzzle实例将转到您的类的构造函数。

如果您有资源/服务类,您仍然可以拥有API客户端类,在这种情况下,这些类不会超过配置入口点和资源类的工厂。

如果您计划在多个项目中重用此客户端,您可能需要考虑使用HTTP客户端抽象(如HTTPlug而不是Guzzle,因为您可能无法在所有项目中安装Guzzle 6(依赖项)冲突等)

最后,但并非最不重要的一点,您可能需要检查this哪些将成为API基础/ bootstrap的确切情况(但尚未完成,因此使用它需要您自担风险)