Erst auflösen, dann lesen
Jede Integration beginnt mit einem getippten Namen und muss bei genau einer Katalog-ID enden. Diese Seite zeigt den Weg dorthin und den Umgang mit Unsicherheit.
Welcher Aufruf welche Frage beantwortet
Drei Endpunkte nehmen eine Zeichenkette entgegen, und keiner beantwortet dieselbe Frage. Der falsche ist der häufigste Grund dafür, dass eine Integration die falsche Waffe zeigt.
| Was Sie haben | Was Sie aufrufen | Warum |
|---|---|---|
| Einen geschriebenen Namen, und Sie brauchen den gemeinten Datensatz | GET /v1/firearms/resolve | Beantwortet, welcher Datensatz eine Zeichenkette ist, und nennt die eigene Sicherheit. Deterministisch: dieselbe Anfrage liefert dauerhaft dieselbe ID. |
| Ein Suchfeld, und Sie brauchen eine Seite plausibler Treffer | GET /v1/firearms/search | Sortiert Datensätze nach Relevanz, damit ein Mensch wählt. Das ist keine Entscheidung, und die erste Zeile ist keine Antwort. |
| Einen Filter, eine Facette oder eine Übersichtsseite | GET /v1/firearms | Strukturierte Filter (Hersteller, Kaliber, Kategorie, Jahr, Verschlussart), die jedes Mal dasselbe bedeuten. Erst hier suchen, dann im Volltext. |
Die Referenz zu beiden steht auf der Resolve-Seite und der Suchseite. Wählt ein Mensch, nehmen Sie die Suche; wählt Ihr Code, nehmen Sie resolve.
Viele Namen auf einmal auflösen
Die Waffen aus einem Dokument, einer Tabellenspalte oder einer Nachricht zu ziehen heißt: Dutzende Namen gleichzeitig. Eine Anfrage pro Name macht aus einer sofortigen Funktion einen Hintergrundjob.
// Fifty names, one round trip. Each result echoes its own query,// so nothing has to be matched up by position.const res = await fetch('https://api.gunspec.io/v1/firearms/resolve', { method: 'POST', headers: { 'X-API-Key': process.env.GUNSPEC_API_KEY, 'Content-Type': 'application/json', }, body: JSON.stringify({ queries: ['G19 gen 5 MOS', 'AK-47', 'H&K MP5', 'that one from Die Hard'], }),}) const { data } = await res.json()for (const result of data.results) { // An unknown name is a result with a status, not an error: one // bad name in fifty does not fail the batch. if (result.status !== 'resolved') { review.push(result) continue } resolved.set(result.query, result.firearmId)}- Bis zu fünfzig Anfragen in einem Aufruf, und jedes Ergebnis wiederholt seine eigene
query. Nichts muss über die Position zugeordnet werden. - Ein unbekannter Name kommt als Ergebnis mit
status: "not_found"zurück, nie als Fehler. Ein schlechter Name lässt die anderen neunundvierzig nicht scheitern. - Ein Batch kostet eine Anfrage vom Kontingent statt fünfzig. Deshalb lohnt er sich auch dort, wo eine Schleife möglich wäre.
Der Score ist eine Entscheidung, keine Zierde
Jedes Ergebnis trägt Status und Score, weil ein Name eindeutig, plausibel oder bedeutungslos sein kann: drei Fälle, drei Verhaltensweisen. Schreiben Sie die Regel einmal und nutzen Sie sie überall dort, wo ein Name ankommt.
// One decision, written once, used everywhere a name arrives.function decide(result) { switch (result.status) { case 'resolved': // Certain enough to act on unattended. Below that, the answer // is probably right, which is not the same thing. return result.score >= 0.9 ? { action: 'use', id: result.firearmId } : { action: 'confirm', id: result.firearmId, from: result.query } case 'ambiguous': // Several records fit equally well and the API deliberately // did not choose. Offer `alternatives`; do not pick [0]. return { action: 'choose', options: result.alternatives } default: // Nothing matched. `unresolvedTokens` names the words that // carried no meaning, which is what to show the user. return { action: 'ask', unresolved: result.unresolvedTokens } }}Fallen Sie nicht stillschweigend auf die Suche zurück. Ein erster Treffer, als Antwort präsentiert, ist der Weg, auf dem die falsche Waffe beim Kunden landet. Ein mehrdeutiges Ergebnis trägt seine Kandidaten bereits, also zeigen Sie sie.
Speichern Sie die ID, nicht den Namen
Die Katalog-ID ist das Stabile in diesem System. Denselben Namen bei jedem Seitenaufruf aufzulösen kostet eine Anfrage, um etwas neu herzuleiten, das sich seit letztem Monat nicht geändert hat.
- Einmal auflösen, die ID neben Ihrem eigenen Datensatz speichern und den Katalog fortan über die ID ansprechen.
- Speichern Sie auch
version: sie ändert sich genau dann, wenn sich ein ausgeliefertes Feld ändert, und sagt ohne weiteren Aufruf, ob Ihre Kopie veraltet ist. Caching und Aktualisierung erklärt den Rest. - Behalten Sie die ursprüngliche Zeichenkette. Wird ein Datensatz zusammengeführt oder umbenannt, führt die Anfrage, die zur ID geführt hat, zurück, ohne die Nutzer erneut zu fragen.
Vier Gewohnheiten, die man ablegen sollte
Jede funktioniert in der Demo und scheitert vor dem Kunden.
| Statt | Besser |
|---|---|
| Suchen und den ersten Treffer nehmen | Auflösen und auf den Status reagieren. Die Suche ist für Menschen zum Auswählen da. |
| Eine ID aus dem Namen raten ("glock-19") | Fragen Sie die API. Slugs folgen dem Katalog, nicht einer Formatierungsregel. |
| Denselben Namen bei jeder Anfrage auflösen | Einmal auflösen, die ID speichern, die Zuordnung beliebig lange cachen. |
| Die nicht getroffenen Wörter verwerfen | unresolvedTokens lesen. Eine Variante, die wir nicht führen, steht dort, statt still zu verschwinden. |