sushi-market/laravel-dadata
Laravel-пакет для работы с API DaData.ru: стандартизация и подсказки адресов, поиск по координатам и другие методы. Поддерживает Laravel 8–10, PHP 7.4–8.1, настраивается через .env (token/secret/timeout), использует Guzzle 7.
Installation:
composer require sushi-market/laravel-dadata
php artisan vendor:publish --provider="SushiMarket\DaData\DaDataServiceProvider"
Add these to .env:
DADATA_TOKEN=your_api_token_here
DADATA_SECRET=your_secret_key_here
DADATA_API_KEY=your_api_key_here
First Use Case: Validate and suggest corrections for a user's address in a form:
use SushiMarket\DaData\Facades\DaData;
$address = '1600 Amphitheatre Parkway, Mountain View';
$result = DaData::suggest('address', $address);
// Output corrected address
dd($result->suggestions[0]->value);
Key Facade Methods:
suggest($type, $query) – Get suggestions for addresses, names, or organizations.clean($type, $query) – Clean and standardize input (e.g., addresses).validate($type, $query) – Validate input against DaData’s rules.// In a controller or service
public function autocomplete(Request $request) {
$query = $request->input('query');
$type = $request->input('type'); // e.g., 'address', 'name'
$suggestions = DaData::suggest($type, $query)
->take(5) // Limit suggestions
->pluck('value');
return response()->json($suggestions);
}
Cache::remember()) to reduce API calls.public function store(Request $request) {
$data = $request->validate([
'address' => 'required|string',
]);
$cleanedAddress = DaData::clean('address', $data['address']);
$data['address'] = $cleanedAddress->result;
// Save to database
User::create($data);
}
after hooks or Observers for global cleaning.$users = User::whereNull('cleaned_address')->get();
foreach ($users as $user) {
$cleaned = DaData::clean('address', $user->address);
$user->update(['address' => $cleaned->result]);
}
dispatch()) for long-running batches.use Illuminate\Validation\Rule;
$rules = [
'address' => [
'required',
Rule::function('dadata_valid_address')
->message('Invalid address. Please correct it.'),
],
];
// In AppServiceProvider::boot()
Validator::extend('dadata_valid_address', function ($attribute, $value, $parameters, $validator) {
return DaData::validate('address', $value)->isValid();
});
Rate Limiting:
// app/Http/Middleware/ThrottleDaData.php
public function handle($request, Closure $next) {
return $next($request)->throttle('dadata', 1, 1); // 1 request per second
}
Error Handling:
try {
$result = DaData::suggest('address', $query);
} catch (\SushiMarket\DaData\Exceptions\DaDataException $e) {
Log::error("DaData API error: " . $e->getMessage());
return back()->withInput()->with('error', 'Service unavailable. Try again later.');
}
Localization:
address.ru, address.ua). Specify in queries:
$result = DaData::suggest('address.ru', $query); // Russian addresses
Testing:
$this->mock(SushiMarket\DaData\Facades\DaData::class, function ($mock) {
$mock->shouldReceive('suggest')
->once()
->andReturn(new \SushiMarket\DaData\Responses\SuggestResponse([...]));
});
Token Management:
DADATA_TOKEN in .env exposes it in version control if not added to .gitignore..env:
echo ".env" >> .gitignore
API Quotas:
429 Too Many Requests.use Symfony\Component\HttpClient\RetryStrategy;
$client = Http::withOptions([
'retry' => RetryStrategy::fromCalls(3, function ($retries, $response) {
return $response->getStatusCode() === 429;
}),
]);
Response Parsing:
suggestions array). Break if not handled dynamically.$suggestions = collect($result->suggestions)->pluck('value');
Character Encoding:
$query = mb_convert_encoding($query, 'UTF-8');
Log Raw Responses:
DADATA_DEBUG=true
storage/logs/laravel.log.Validate API Keys:
Common Errors:
401 Unauthorized: Invalid DADATA_TOKEN or DADATA_SECRET.400 Bad Request: Malformed query (e.g., empty string, unsupported type).500 Server Error: DaData server-side issue (check status page).Custom Response Handlers:
SushiMarket\DaData\Responses\BaseResponse class to add custom logic:
class CustomResponse extends BaseResponse {
public function getFormattedAddress() {
return $this->result . ', ' . $this->postal_code;
}
}
Add New DaData Services:
bank-resident, phone). Extend the package:
// app/Providers/DaDataServiceProvider.php
public function register() {
$this->app->singleton('dadata.bank-resident', function () {
return new \SushiMarket\DaData\Services\BankResidentService();
});
}
Webhook Integration:
Route::post('/dadata-webhook', function (Request $request) {
$event = $request->input('event');
if ($event === 'address.updated') {
AddressUpdatedJob::dispatch($request->input('data'));
}
});
Fallback Mechanisms:
try {
$result = DaData::suggest('
How can I help you explore Laravel packages today?