我将从头开始创建一个用于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类?
答案 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的确切情况(但尚未完成,因此使用它需要您自担风险)