Integraties
SDK's en plugins
We geven geen pakket uit dat je moet installeren en bijhouden. De API is één GET-verzoek met één header; daar heb je geen laag omheen voor nodig. Wat je hier vindt is werkende code die je rechtstreeks in je project plakt, met caching en foutafhandeling er al in.
In alle voorbeelden staat de publieke sandboxsleutel al ingevuld, dus ze doen het meteen. Vervang hem door je eigen sleutel als je live gaat.
De basis
Een adres opzoeken
Hetzelfde verzoek in negen talen, compleet met foutafhandeling.
curl -sS -i \
-H "X-Api-Key: lat_test_demo_publiek_locatieapi_sandbox" \
-H "Accept: application/json" \
"https://api.locatieapi.nl/v3/lookup/1021JT/19"
WordPress
Een kleine plugin
Server-side aanroep achter een AJAX-actie, met een nonce en een transient als cache. Zet je sleutel in wp-config.php als constante LOCATIEAPI_KEY.
<?php
/**
* Plugin Name: LocatieAPI adresaanvulling
* Description: Vult straat en plaats aan op basis van postcode en huisnummer.
* Version: 1.0.0
*/
add_action('wp_ajax_locatieapi_lookup', 'locatieapi_lookup');
add_action('wp_ajax_nopriv_locatieapi_lookup', 'locatieapi_lookup');
function locatieapi_lookup()
{
check_ajax_referer('locatieapi', 'nonce');
$postcode = strtoupper(preg_replace('/\s+/', '', sanitize_text_field($_GET['postcode'] ?? '')));
$number = (int) ($_GET['number'] ?? 0);
$cacheKey = 'locatieapi_'.$postcode.'_'.$number;
$cached = get_transient($cacheKey);
if ($cached !== false) {
wp_send_json($cached);
}
$response = wp_remote_get("https://api.locatieapi.nl/v3/lookup/{$postcode}/{$number}", [
'timeout' => 5,
'headers' => ['X-Api-Key' => LOCATIEAPI_KEY, 'Accept' => 'application/json'],
]);
if (is_wp_error($response) || wp_remote_retrieve_response_code($response) !== 200) {
wp_send_json_error(['message' => 'Adres niet gevonden'], 404);
}
$address = json_decode(wp_remote_retrieve_body($response), true);
set_transient($cacheKey, $address, DAY_IN_SECONDS);
wp_send_json($address);
}
Zet je sleutel niet in een optie
Een optie die je in een template uitleest belandt zo in de broncode van je pagina. Gebruik een constante inwp-config.php, buiten de webroot als dat
kan, en houd de aanroep server-side.
WooCommerce
Adresaanvulling in de checkout
Vult straat en plaats aan zodra postcode en huisnummer ingevuld zijn, via de AJAX-actie uit de plugin hierboven.
<?php
/**
* Vult in de WooCommerce-checkout straat en plaats aan zodra postcode en
* huisnummer ingevuld zijn. De sleutel blijft server-side.
*/
add_action('woocommerce_after_checkout_form', function () {
$nonce = wp_create_nonce('locatieapi');
$endpoint = admin_url('admin-ajax.php');
?>
<script>
(function () {
const postcode = document.getElementById('billing_postcode');
const number = document.getElementById('billing_address_1');
if (!postcode || !number) return;
async function fill() {
const pc = postcode.value.replace(/\s+/g, '').toUpperCase();
const nr = parseInt(number.value, 10);
if (!/^[0-9]{4}[A-Z]{2}$/.test(pc) || !nr) return;
const url = new URL('<?php echo esc_js($endpoint); ?>', window.location.origin);
url.searchParams.set('action', 'locatieapi_lookup');
url.searchParams.set('nonce', '<?php echo esc_js($nonce); ?>');
url.searchParams.set('postcode', pc);
url.searchParams.set('number', String(nr));
const response = await fetch(url);
if (!response.ok) return;
const address = await response.json();
document.getElementById('billing_address_2').value = address.street;
document.getElementById('billing_city').value = address.city;
}
postcode.addEventListener('blur', fill);
number.addEventListener('blur', fill);
})();
</script>
<?php
});
- •Laat de velden bewerkbaar. Een klant die op een adres woont dat administratief net anders heet moet gewoon kunnen bestellen.
- •Vul alleen aan als het veld nog leeg is of als de postcode is gewijzigd, zodat je een handmatige correctie niet overschrijft.
- •Werk je met een blocks-checkout, hang de aanroep dan aan de store-API in plaats van aan de classic-veldnamen.
Magento 2
Een service in je eigen module
Registreer hem in di.xml en roep hem aan vanuit een controller onder frontend, nooit rechtstreeks vanuit de browser met je livesleutel.
<?php
declare(strict_types=1);
namespace Score\LocatieApi\Model;
use Magento\Framework\App\CacheInterface;
use Magento\Framework\HTTP\Client\Curl;
use Magento\Framework\Serialize\SerializerInterface;
/**
* Adresopzoeker voor Magento 2. Registreer hem als service en roep hem aan
* vanuit een controller onder frontend/, nooit rechtstreeks vanuit de browser.
*/
class AddressLookup
{
private const BASE = 'https://api.locatieapi.nl';
public function __construct(
private readonly Curl $curl,
private readonly CacheInterface $cache,
private readonly SerializerInterface $serializer,
private readonly string $apiKey,
) {
}
public function find(string $postcode, int $number): ?array
{
$postcode = strtoupper(preg_replace('/\s+/', '', $postcode));
$cacheKey = 'locatieapi_'.$postcode.'_'.$number;
$cached = $this->cache->load($cacheKey);
if ($cached) {
return $this->serializer->unserialize($cached);
}
$this->curl->setTimeout(5);
$this->curl->addHeader('X-Api-Key', $this->apiKey);
$this->curl->addHeader('Accept', 'application/json');
$this->curl->get(self::BASE."/v3/lookup/{$postcode}/{$number}");
if ($this->curl->getStatus() !== 200) {
return null;
}
$address = $this->serializer->unserialize($this->curl->getBody());
$this->cache->save($this->serializer->serialize($address), $cacheKey, [], 86400);
return $address;
}
}
JavaScript
Autocomplete rechtstreeks vanuit de browser
Dit mag bij ons, mits je de toegestane origins op de sleutel zet en er een sleutel met alleen leesrechten voor gebruikt.
/**
* Autocomplete rechtstreeks vanuit de browser. Dat mag met LocatieAPI,
* mits je de origin op de sleutel zet en een sleutel met alleen
* leesrechten gebruikt.
*/
const KEY = 'lat_test_demo_publiek_locatieapi_sandbox';
async function suggest(term) {
if (term.length < 2) return [];
const url = new URL('https://api.locatieapi.nl/v1/autocomplete');
url.searchParams.set('q', term);
url.searchParams.set('type', 'address');
url.searchParams.set('limit', '8');
const response = await fetch(url, { headers: { 'X-Api-Key': KEY } });
if (!response.ok) return [];
const { data } = await response.json();
return data.map((row) => row.label);
}
const input = document.querySelector('#adres');
let timer;
input.addEventListener('input', () => {
clearTimeout(timer);
timer = setTimeout(async () => {
const options = await suggest(input.value);
document.querySelector('#suggesties').replaceChildren(
...options.map((label) => Object.assign(document.createElement('option'), { value: label })),
);
}, 150);
});
Python
Een kleine client met cache
Met een sessie die de header vasthoudt, een cache en een terugval die niets stukmaakt als de API even niet bereikbaar is.
"""Kleine client met caching en een nette terugval."""
from functools import lru_cache
import requests
BASE = "https://api.locatieapi.nl"
KEY = "lat_test_demo_publiek_locatieapi_sandbox"
session = requests.Session()
session.headers.update({"X-Api-Key": KEY, "Accept": "application/json"})
@lru_cache(maxsize=4096)
def lookup(postcode: str, number: int) -> dict | None:
postcode = postcode.replace(" ", "").upper()
try:
response = session.get(f"{BASE}/v3/lookup/{postcode}/{number}", timeout=5)
except requests.RequestException:
return None
if response.status_code == 404:
return None
response.raise_for_status()
return response.json()
if __name__ == "__main__":
print(lookup("1021 JT", 19))
Staat jouw stack er niet bij?
Gebruik het instructieblok voor je codeerassistent: dat zet de hele specificatie plus de opdracht om er in jouw project een adresopzoeker mee te bouwen op je klembord, met varianten voor Laravel, Next.js, WordPress en Python.