Anagram Server ist eine node.js-basierte Anwendung, die eine restgestützte API für die Durchführung von Anagram-bezogenen Suchanfragen gegen ein Wörterbuch von Wörtern aufdeckt. Sein Hauptmerkmal ist es, bekannte Anagramme für ein bestimmtes Wort zu finden.
Darüber hinaus können Anagram -Mengen (Gruppen von Wörtern, die Anagramme voneinander ausmachen) durch Kardinalität (Anzahl der Wörter im Satz) oder eine Wortlänge abgefragt werden. Es ist auch möglich zu fragen, ob ein bestimmter Satz von Wörtern ein Anagrammsatz umfasst.
Das Wörterbuch von Wörtern, gegen die Anagramme abgefragt werden können, kann hinzugefügt, gelöscht oder vollständig über die API gelöscht werden. Wenn Anagram Server beim Start als app.js
als nur Speicherdienste konfiguriert wird (dh nicht über Service-Neustarts in den Service-Neustarts).
Schließlich kann eine Reihe von Statistiken über das geladene Wörterbuch über die API abgefragt werden.
Installieren Sie bei Bedarf Node.js
Installieren Sie NPM -Abhängigkeiten
npm install
npm start
Standardmäßig dient die App Anfragen über Port 3000. Um dies zu überschreiben, können Sie das Startskript in package.json
aktualisieren, um eine alternative Portnummer an den Befehl node zu übergeben. Zum Beispiel:
"start": "node src/app.js -p 8080"
Möglicherweise müssen Sie den eingehenden Verkehr auf dem effektiven Port explizit zulassen. So öffnen Sie Port 3000 auf Linux bis zum nächsten Neustart:
sudo iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 3000 -j ACCEPT
Installieren Sie bei Bedarf Docker
Erstellen Sie das Docker -Bild
sudo docker build -t anagram-server .
sudo docker run -p 3000:3000 anagram-server
Möglicherweise ziehen Sie es vor, einen alternativen Host -Port zuzuordnen (z. B. -p 8080:3000
).
Der Anagram -Server wird mit Ruby -Testskripten geliefert.
Beachten Sie, dass der Anagram -Server standardmäßig vor dem Start vor dictionary.txt
.
Die Testskripte befinden sich im test
-Unterordner des Quellpakets und können einzeln wie folgt ausgeführt werden:
ruby anagram_test.rb
ruby anagram_test_2.rb
Anagram Server kann manuell mit cURL
oder einem Tool wie Postboten getestet werden. Zum Beispiel (aus der Befehlszeile in einem neuen Terminalfenster des App -Hosts):
curl -i "http://localhost:3000/anagrams/shout.json"
Da standardmäßig der Anagram -Server vor dem Testen das dictionary.txt
vor dem Testen mit dem folgenden Befehl mit dem folgenden Befehl löschen möchte, sollten Sie standardmäßig vor dem Testen das Dictionary löschen.
curl -i -X DELETE "http://localhost:3000/words.json"
Ersetzen Sie zum Ferntest "Localhost" durch den App -Host -IP in anagram_client.rb
und in den Beispielbefehlen dieses Dokuments.
Aktualisieren Sie auch die Portnummer in anagram_client.rb
und in den Beispielbefehlen, wenn Sie Anagram Server mit einem anderen Port als Standard ausführen (3000).
Ein Wort wird als gültig angesehen, wenn es eine Kombination aus Groß- und Kleinbuchstaben -englischen Alphabetbuchstaben oder einem Bindestrich enthält. Ein gültiges Wort startet oder endet möglicherweise nicht mit einem Bindestrich.
Versuche, ungültige Wörter zu erhalten oder zu löschen, führen zu 400 Bad Request
.
Versuche, ungültige Wörter zu veröffentlichen, führen zu 204 No Content
.
Ein ordnungsgemäßes Substantiv gilt als ein Wort, das alle Kleinbuchstaben mit Ausnahme des ersten Buchstabens (der sich in Großbuchstaben befindet) und den ersten Buchstaben nach einem Bindestrich (der in Großbuchstaben oder Kleinbuchstaben sein kann).
Einige Beispiele sind: Englisch, Zulu, Jean-Christophe
Die richtigen Substantive unterscheiden sich von ihren Kleinkappenversionen. ZB, Abigail und Abigail sind zwei verschiedene Wörter (und Anagramme voneinander).
Angemessene Substantive sind immer in Ergebnissen enthalten, sofern sie nicht ausdrücklich ausgeschlossen sind (siehe excludeProperNouns
Parm von GET /anagrams/:word.json
).
Der Anagram Server ermöglicht es aus Gründen der Einschätzung, in einigen Fällen die richtigen Substantive gegen ihre Kleinbuchstabenversionen zu entsprechen. Zum Beispiel bei Abfragen von Anagrammen:
$ curl -i "http://localhost:3000/anagrams/aaru.json?includeInput=true"
HTTP/1.1 200 OK
Content-Type: application/json
...
{ "anagrams": [
"Aaru",
"aura"]
}
Die Anagram Server-Architektur besteht aus 4 Schichten (von niedrigster bis zum höchster):
Ein Adapter ist eine Klasse, die die von Anagram Server verwendeten grundlegenden storespezifischen Abfragen, Iteraten und CRUD-Operationen bereitstellt. Insbesondere bietet ein Adapter eine Semantik zum Zusammenhang mit einer Schlüsselzeichenfolge mit einer Reihe von Werten, addiert und löschen von der Wertemenge pro Taste, Abfragen nach einem Set nach Schlüssel und Iterating -Taste/-satzpaare.
Der Adapter wird die Besonderheiten des zugrunde liegenden Speichermechanismus aus der Servicelogik abstrahiert, um den Austausch einer Speicher -Technologie gegen eine andere zu erleichtern. Ein Wert dieser Abstraktion besteht darin, einen einfachen Upgrade -Pfad zu bieten, wenn günstigere Speicheralternativen auftauchen und flexible Skalierbarkeitsoptionen ermöglichen.
Beispielsweise kann der Dienst zunächst als einzelner App -Server mit einem Adapter eingeführt werden, der eine MySQL -Instanz auf denselben Server einbindet. Wenn Skalierbarkeit, Failover und Leistungsbedürfnisse zunehmen, können wir den Adapter gegen einen, der eine Redis -Instanz einbringt, die seine Daten über mehrere Server hinweg anhält und wiederholt. Die Besonderheiten der Daten werden gespeichert, zwischengespeichert und/oder repliziert für den Anagram -Dienst sind transparent.
Der Anagram -Server wird mit MemoryAdapter ( adapters/MemoryAdapter.js
) geliefert, das die Karte von JavaScript verwendet, um Daten zu speichern und abzufragen. Dieser Adapter verfügt über eine begrenzte Anwendung, da er nicht den Vorteil der Persistenz über Server -Neustarts hinweg bietet, aber als gute Grundlage für das Testen und die Darstellung von Anagram Server -Funktionen dient.
Das Projekt definiert eine Schnittstelle zum Implementieren von Adaptern in den adapters/adapter-template.js
. Diese Datei kann als Kesselplatte zum Definieren neuer Adapter verwendet werden.
Die Adapterschnittstelle ist vielversprechend, da APIs für Speichertechnologien in der Regel asynchron sind. Theoretisch fügt dies die Reaktionszeit hinzu, da Versprechen über die Ereigniswarteschlange gelöst werden. Dieser Effekt ist jedoch im Rahmen einer Netzwerkanforderung vernachlässigbar.
Transaktionen
Die Methoden add()
und delete()
des Adapters erfordern das zugrunde liegende Speicher, um Transaktionen zu unterstützen, da ihre Logik die Abfrage der Daten beinhaltet und dann im Store basierend auf den Ergebnissen der Abfrage arbeitet.
Klonenergebnisse
MemoryAdapter get()
und each()
-Methode gibt Kartenwert -Arrays direkt an den AnagramService zurück. Dies erfordert Fleiß im Namen des AnagramService -Code, um eine zufällige Mutation der mit diesen Methoden lieferten Ergebnisse zu vermeiden.
Das Klonen der Ergebnisse innerhalb von MemoryAdapter vor der Rückkehr wäre ein kluger Schritt, um zukünftige Fehler zu mildern, die Konsistenz der Schnittstelle zu gewährleisten und den Verbrauchern die geringste Erstaunen zu ermöglichen, aber auch zusätzliche (wenn auch wahrscheinlich vernachlässigbare) Aufwand.
AnagramService ist eine Klasse, die die Geschäftslogik für den Anagram -Server bereitstellt. Es erfordert eine Instanz eines Adapters, um an seinen Konstruktor übergeben zu werden.
Die AnagramService -Klasse behält Word- und Anagram -Zählungen bei und implementiert Methoden, die die Rest -API direkt unterstützen.
Diese Klasse lebt in AnagramService.js
.
server.js
exportiert eine einzelne Funktion startServer()
, die den Restserver (über restify) erstellt und AnagramService instanziiert.
startServer()
benötigt eine Adapterinstanz und akzeptiert optional eine Portnummer, aus der es zu Serviceanforderungen und einen optionalen Pfad zu einer Textdatei wird, um das Wörterbuch aus zu präpopulieren.
Das Fleisch von server.js
ist die Reihe der Server -Antwortfunktionen, die einzelne HTTP -Anforderungen analysieren, die entsprechenden AnagramService -Methoden aufrufen und Antworten mit geeigneten Objektverpackungen und HTTP -Antwortcodes ausstellen.
app.js
ist der Einstiegspunkt für Anagram Server. Es handelt sich um eine einfache Datei, die den Adapter angibt, der den Dienst mit und eine optionale Datenvorladungsquelle ausführt.
Dies ist die einzige Datei, die sich ändern muss, wenn Sie einen Adapter gegen einen anderen austauschen.
In der aktuellen Version von app.js
wird AnagramServer mit dem MemoryAdapter- und Preloads dictionary.txt
beim Start ausgeführt.
Im Folgenden finden Sie einige Ideen für die Weiterentwicklung von Anagram Server.
GET /anagrams/:word.json
Geben Sie eine JSON -Reihe von Wörtern zurück, die Anagramme des Wortes in der URL sind.
Wenn das übergebene Wort selbst kein bekanntes Wort ist (dh nicht im Wörterbuch), wird ein leeres Array zurückgegeben (auch wenn aus dem übergebenen Wort bekannte Anagramme gebildet werden können).
Aus Bequemlichkeit entspricht ein als Kleinbuchstaben bestandenes Wort mit seinem richtigen Substantivformular.
Beispiel:
$ curl -i "http://localhost:3000/anagrams/care.json"
HTTP/1.1 200 OK
Content-Type: application/json
...
{ "anagrams": [
"Acer",
"acre",
"crea",
"race"]
}
GET /anagrams/:word.json?limit=<integer>
Geben Sie ein JSON -Array von Wörtern zurück, die Anagramme des in der URL übergebenen Wortes sind, begrenzen jedoch die Anzahl der zurückgegebenen Ergebnisse .
Beispiel:
$ curl -i "http://localhost:3000/anagrams/care.json?limit=2"
HTTP/1.1 200 OK
Content-Type: application/json
...
{ "anagrams": [
"Acer",
"acre"]
}
GET /anagrams/:word.json?includeInput=true
Geben Sie ein JSON -Array von Wörtern zurück, die Anagramme des Wortes sind, das in der URL übergeben wurde, einschließlich des Eingangsworts selbst .
Das Eingangswort ist normalerweise nicht in Anagram -Ergebnissen enthalten, da ein Wort nicht konventionell als Anagramm von sich selbst angesehen wird.
$ curl -i "http://localhost:3000/anagrams/care.json?includeInput=true"
HTTP/1.1 200 OK
Content-Type: application/json
...
{ "anagrams": [
"Acer",
"acre",
"care",
"crea",
"race"]
}
GET /anagrams/:word.json?excludeProperNouns=true
Geben Sie eine JSON -Reihe von Wörtern zurück, die Anagramme des Wortes in der URL sind und die richtigen Substantive weglassen .
Die richtigen Substantive sind normalerweise in Anagram -Ergebnissen enthalten.
$ curl -i "http://localhost:3000/anagrams/care.json?limit=2&excludeProperNouns=true"
HTTP/1.1 200 OK
Content-Type: application/json
...
{ "anagrams": [
"acre",
"crea"]
}
GET /anagrams?cardinalityMin=<integer>&cardinalityMax=<integer>
Geben Sie alle Anagram -Sätze mit einer minimalen und/oder maximalen Kardinalität zurück (Anzahl der Anagramme im Set).
Entweder kann Cardinalitymin oder CardinalityMax weggelassen werden.
Beispiele:
$ curl -i "http://localhost:3000/anagrams?cardinalityMin=3&cardinalityMax=4"
HTTP/1.1 200 OK
Content-Type: application/json
...
{
"anagramsByCardinality": {
"cardinalityMin": 3,
"cardinalityMax": 4,
"anagrams": [
["Aaronic", "Nicarao", "ocarina"],
["abater", "artabe", "eartab", "trabea"],
["Abe", "bae", "Bea"],
...
]
}
}
# Return all words that have anagrams
$ curl -i "http://localhost:3000/anagrams?cardinalityMin=2"
HTTP/1.1 200 OK
Content-Type: application/json
...
{
"anagramsByCardinality": {
"cardinalityMin": 2,
"anagrams": [
["A", "a"],
["aal", "ala"],
["aam", "ama"],
...
]
}
}
GET /anagrams?lengthMin=<integer>&lengthMax=<integer>
Geben Sie alle Anagram -Sätze zurück, die eine minimale und/oder maximale Wortlänge haben.
Entweder Länge oder Längemax kann weggelassen werden.
Beispiel:
$ curl -i "http://localhost:3000/anagrams?lengthMin=10&lengthMax=11"
HTTP/1.1 200 OK
Content-Type: application/json
...
{
"anagramsByLength": {
"lengthMin": 10,
"lengthMax": 11,
"anagrams": [
["ablastemic", "masticable"],
["aborticide", "bacterioid"],
["acalyptrate", "Calyptratae"],
...
]
}
}
GET /anagrams?maxCardinality=true
Geben Sie alle Anagram -Sätze mit der maximalen Kardinalität zurück.
Beispiel:
$ curl -i "http://localhost:3000/anagrams?maxCardinality=true"
HTTP/1.1 200 OK
Content-Type: application/json
...
{
"maxCardinalityAnagrams": {
"maxCardinality": 11,
"anagrams": [
["angor", "argon", "goran", "grano", "groan", "nagor", "Orang", "orang", "organ", "rogan", "Ronga"]
]
}
}
GET /anagrams?maxLength=true
Geben Sie alle Anagram -Sätze mit der maximalen Wortlänge zurück.
Beispiel:
$ curl -i "http://localhost:3000/anagrams?maxLength=true"
HTTP/1.1 200 OK
Content-Type: application/json
...
{
"maxLengthAnagrams": {
"maxLength": 22,
"anagrams": [
["cholecystoduodenostomy", "duodenocholecystostomy"],
["hydropneumopericardium", "pneumohydropericardium"]
]
}
}
GET /anagrams?areAnagrams=<comma-delimited list of words>
Bestimmen Sie, ob ein Satz von Wörtern Anagramme voneinander sind.
Alle vergangenen Wörter müssen (dh im Wörterbuch) bekannt sein, damit dies wahr ist.
Beispiel:
$ curl -i "http://localhost:3000/anagrams?areAnagrams=acer,acre,race"
HTTP/1.1 200 OK
Content-Type: application/json
...
{
"anagramAffinity": {
"areAnagrams": true,
"words": ["acer", "acre", "race"]
}
}
GET /anagrams?count=true
Return Anagram zählt nur. Jeder Satz von Anagrammen im Wörterbuch fügt N-1 zu dieser Zählung hinzu, wobei n die Anzahl der Anagramme im Set ist.
Beispiel:
$ curl -i "http://localhost:3000/anagrams?count=true"
HTTP/1.1 200 OK
Content-Type: application/json
...
{ "counts": { "anagram": 20043 }}
GET /words?count=true
Rückgabe der Anzahl der Wörter im Wörterbuch.
Beispiel:
$ curl -i "http://localhost:3000/words?count=true"
HTTP/1.1 200 OK
Content-Type: application/json
...
{ "counts": { "word": 235886 }}
GET /words?stats=true
Geben Sie einige Statistiken über die Wörter im Wörterbuch zurück.
Beispiel:
$ curl -i "http://localhost:3000/words?stats=true"
HTTP/1.1 200 OK
Content-Type: application/json
...
{
"stats": {
"wordCount": 235886,
"anagramCount": 20043,
"minWordLength": 1,
"maxWordLength": 24,
"medianWordLength": 4,
"averageWordLength": 9.569126612007494,
"minCardinality": 2,
"maxCardinality": 11,
"medianCardinality": 2,
"averageCardinality": 2.3111140184470464
}
}
POST /words.json
Nimmt eine JSON -Reihe von Wörtern und fügt sie dem Wörterbuch hinzu.
Beispiel:
$ curl -i -X POST -d '{ "words": ["Canadas", "acandas", "Smurfs", "care"] }' "http://localhost:3000/words.json"
HTTP/1.1 201 Created
Content-Type: application/json
...
{
"counts": {
"word": 3,
"anagram": 1
},
"words": ["/anagrams/Canadas", "/anagrams/acandas", "/anagrams/Smurfs"]
}
DELETE /words/:word.json
Löschen Sie ein einzelnes Wort aus dem Wörterbuch.
Wenn das vergangene Wort selbst kein bekanntes Wort ist (dh nicht im Wörterbuch), wird ein 404
zurückgegeben.
Beispiel:
$ curl -i -X DELETE "http://localhost:3000/words/care.json"
HTTP/1.1 204 No Content
...
DELETE /words/:word.json?includeAnagrams=true
Löschen Sie ein einzelnes Wort und alle seine Anagramme aus dem Wörterbuch.
Wenn das vergangene Wort selbst kein bekanntes Wort ist (dh nicht im Wörterbuch), wird nichts gelöscht und ein 404
wird zurückgegeben.
Beispiel:
$ curl -i -X DELETE "http://localhost:3000/words/acre.json?includeAnagrams=true"
HTTP/1.1 204 No Content
...
DELETE /words.json
Entfernen Sie alle Inhalte aus dem Wörterbuch.
Beispiel:
$ curl -i -X DELETE "http://localhost:3000/words.json"
HTTP/1.1 204 No Content
...