Laravel 11消费第三方API最佳实践:Google Maps自动补全场景
Laravel 11 消费第三方API的最佳实践(以Google Maps自动补全为例)
核心思路:用服务类封装第三方API逻辑
你的Livewire组件应该专注于UI交互和数据绑定,API调用、结果格式化这类逻辑属于服务层职责,单独抽离到服务类是Laravel的标准最佳实践,比塞在组件、Model或ServiceProvider里更合理。
具体实现步骤
1. 创建Google Maps服务类
在app/Services目录下新建GoogleMapsAutocompleteService.php(如果Services目录不存在,直接创建即可):
<?php namespace App\Services; use Illuminate\Support\Facades\Http; class GoogleMapsAutocompleteService { protected $apiKey; public function __construct() { $this->apiKey = env('GOOGLE_MAPS_API_KEY'); } // 封装自动补全查询逻辑 public function getPredictions(string $input): array { if (empty($input)) { return []; } $response = Http::get('https://maps.googleapis.com/maps/api/place/autocomplete/json', [ 'key' => $this->apiKey, 'type' => 'political', 'components' => 'country:us|country:ca', 'input' => $input ]); // 处理请求失败或无结果的情况 if (!$response->successful() || !isset($response->object()->predictions)) { return []; } // 格式化返回结果为需求的格式 return collect($response->object()->predictions)->map(function ($prediction) { $nameParts = []; $termsCount = count($prediction->terms); $nameParts[] = $prediction->terms[0]->value; if ($termsCount > 3) { $nameParts[] = $prediction->terms[$termsCount - 3]->value; $nameParts[] = $prediction->terms[$termsCount - 2]->value; } else { $nameParts[] = $prediction->terms[1]->value; } return [ 'id' => $prediction->place_id, 'name' => implode(', ', $nameParts) ]; })->toArray(); } }
2. 改造Livewire组件
通过Laravel的自动依赖注入,在组件中调用服务类的方法,简化组件逻辑:
<?php namespace App\Livewire; use Livewire\Component; use App\Services\GoogleMapsAutocompleteService; class LocationSearch extends Component { public $location = ''; public $results = []; #[Modelable] public $selected = []; public function updatedLocation($value, GoogleMapsAutocompleteService $service) { $this->reset('results'); // 直接调用服务类的方法获取格式化后的结果 $this->results = $service->getPredictions($value); } public function valueSelected($id, $name) { $this->location = $name; $this->selected = [ 'id' => $id, 'name' => $name ]; $this->reset('results'); } public function render() { return view('livewire.location-search'); } }
为什么选服务类而不是其他?
- Model:Model是对应数据库表的实体类,和第三方API逻辑完全不相关,违背单一职责原则。
- ServiceProvider:ServiceProvider的作用是注册服务到容器、加载配置/路由等,不是用来封装业务逻辑的。只有当你的服务需要复杂初始化(比如多个依赖、自定义绑定)时才需要用它,这里自动注入已经足够。
- 服务类的优势:逻辑集中便于维护、可单独编写单元测试(比如模拟Http请求)、其他模块需要调用Google自动补全时可以直接复用,符合代码复用和分离关注点的设计原则。
内容的提问来源于stack exchange,提问作者Yev
相关产品推荐
相关产品推荐

