ANAGRAM SERVER เป็นแอปพลิเคชั่นที่ใช้ Node.js ที่เปิดเผย API ที่ใช้ REST สำหรับการค้นหาที่เกี่ยวข้องกับ ANAGRAM กับพจนานุกรมของคำ คุณสมบัติหลักของมันคือการค้นหาแอนนาแกรมที่รู้จักสำหรับคำที่กำหนด
นอกจากนี้ชุดแอนนาแกรม (กลุ่มของคำที่เป็นแอนนาแกรมของกันและกัน) สามารถสอบถามได้โดย cardinality (จำนวนคำในชุด) หรือความยาวของคำ นอกจากนี้ยังเป็นไปได้ที่จะสอบถามว่าชุดคำที่กำหนดประกอบด้วยชุดแอนนาแกรมหรือไม่
พจนานุกรมของคำที่สามารถสอบถามแอนนาแกรมสามารถเพิ่มได้ลบออกจากหรือเคลียร์ทั้งหมดผ่าน API เมื่อกำหนดค่าเป็นบริการเฉพาะหน่วยความจำ (เช่นการเปลี่ยนแปลงที่ไม่ได้รับการยืนยันในการรีสตาร์ทบริการ), เซิร์ฟเวอร์ Anagram preloads ชุดคำภาษาอังกฤษมาตรฐานเมื่อเริ่มต้น (ดู app.js
)
ในที่สุดสถิติจำนวนหนึ่งเกี่ยวกับพจนานุกรมที่โหลดสามารถสอบถามได้ผ่าน API
ติดตั้ง node.js หากจำเป็น
ติดตั้งการพึ่งพา NPM
npm install
npm start
โดยค่าเริ่มต้นแอปจะให้บริการคำขอผ่านพอร์ต 3000 เพื่อแทนที่สิ่งนี้คุณสามารถอัปเดตสคริปต์เริ่มต้นใน package.json
เพื่อส่งหมายเลขพอร์ตอื่นไปยังคำสั่ง Node ตัวอย่างเช่น:
"start": "node src/app.js -p 8080"
คุณอาจต้องอนุญาตให้มีการรับส่งข้อมูลขาเข้าบนพอร์ตที่มีประสิทธิภาพอย่างชัดเจน ตัวอย่างเช่นในการเปิดพอร์ต 3000 บน Linux จนกว่าจะรีบูตถัดไป:
sudo iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 3000 -j ACCEPT
ติดตั้ง Docker หากจำเป็น
สร้างภาพนักเทียบท่า
sudo docker build -t anagram-server .
sudo docker run -p 3000:3000 anagram-server
คุณอาจต้องการทำแผนที่ไปยังพอร์ตโฮสต์ทางเลือก (เช่น -p 8080:3000
)
เซิร์ฟเวอร์ Anagram จัดส่งสคริปต์ทดสอบทับทิม
โปรดทราบว่าโดยค่าเริ่มต้นเซิร์ฟเวอร์ Anagram preloads preloads จาก dictionary.txt
เมื่อเริ่มต้น
สคริปต์ทดสอบอยู่ในโฟลเดอร์ test
ของแพ็คเกจต้นทางและสามารถเรียกใช้เป็นรายบุคคลได้เช่น:
ruby anagram_test.rb
ruby anagram_test_2.rb
เซิร์ฟเวอร์ Anagram สามารถทดสอบได้ด้วยตนเองด้วย cURL
หรือเครื่องมือเช่นบุรุษไปรษณีย์ ตัวอย่างเช่น (จากบรรทัดคำสั่งในหน้าต่างเทอร์มินัลใหม่ของโฮสต์แอป):
curl -i "http://localhost:3000/anagrams/shout.json"
ตั้งแต่ค่าเริ่มต้นคำว่าเซิร์ฟเวอร์ Anagram preloads จาก dictionary.txt
เมื่อเริ่มต้นคุณอาจต้องการล้างพจนานุกรมด้วยคำสั่งต่อไปนี้ก่อนการทดสอบ:
curl -i -X DELETE "http://localhost:3000/words.json"
สำหรับการทดสอบระยะไกลให้แทนที่ "localhost" ด้วย IP โฮสต์แอปใน anagram_client.rb
และในคำสั่งตัวอย่างของเอกสารนี้
นอกจากนี้ยังอัปเดตหมายเลขพอร์ตใน anagram_client.rb
และในคำสั่งตัวอย่างหากเรียกใช้เซิร์ฟเวอร์ Anagram ที่มีพอร์ตอื่นนอกเหนือจากค่าเริ่มต้น (3000)
คำนั้นถือว่าถูกต้องหากมีการรวมกันของตัวพิมพ์ใหญ่และตัวอักษรตัวอักษรภาษาอังกฤษตัวพิมพ์เล็กหรือยัติภังค์ คำที่ถูกต้องอาจไม่ เริ่ม หรือ จบ ด้วยยัติภังค์
ความพยายามในการรับหรือลบคำที่ไม่ถูกต้องส่งผลให้มี 400 Bad Request
ความพยายามที่จะโพสต์คำที่ไม่ถูกต้องส่งผลให้ 204 No Content
คำนามที่เหมาะสมถือเป็นคำใด ๆ ที่มีตัวอักษรตัวพิมพ์เล็กทั้งหมดยกเว้นตัวอักษรตัวแรก (ซึ่งต้องเป็นตัวพิมพ์ใหญ่) และตัวอักษรตัวแรกหลังจากยัติภังค์ (ซึ่งอาจเป็นตัวพิมพ์ใหญ่หรือตัวพิมพ์เล็ก)
ตัวอย่างบางส่วนคือ: ภาษาอังกฤษ, ซูลู, ฌอง-คริสโตเฟ่
คำนามที่เหมาะสมถือว่าแตกต่างจากรุ่นตัวพิมพ์เล็กของพวกเขา เช่น อาบิกายิล และ อาบิกายิล เป็นสองคำที่แตกต่างกัน (และแอนนาแกรมซึ่งกันและกัน)
คำนามที่เหมาะสมจะรวมอยู่ในผลลัพธ์เสมอเว้นแต่จะได้รับการยกเว้นอย่างชัดเจน (ดู excludeProperNouns
parm ของ GET /anagrams/:word.json
)
เพื่อความสะดวกเซิร์ฟเวอร์แอนนาแกรมอนุญาตให้จับคู่คำนามที่เหมาะสมกับเวอร์ชันตัวพิมพ์เล็กในบางกรณี ตัวอย่างเช่นเมื่อสอบถามแอนนาแกรม:
$ curl -i "http://localhost:3000/anagrams/aaru.json?includeInput=true"
HTTP/1.1 200 OK
Content-Type: application/json
...
{ "anagrams": [
"Aaru",
"aura"]
}
สถาปัตยกรรมเซิร์ฟเวอร์แอนนาแกรมประกอบด้วย 4 เลเยอร์ (จากระดับต่ำสุดถึงสูงสุด):
อะแดปเตอร์เป็นคลาสที่ให้บริการการสืบค้นเฉพาะร้านค้าขั้นพื้นฐานการทำซ้ำและการดำเนินการ CRUD ที่ใช้โดยเซิร์ฟเวอร์ Anagram โดยเฉพาะอะแดปเตอร์ให้ความหมายสำหรับการเชื่อมโยงสตริงคีย์เข้ากับชุดของค่าเพิ่มและลบออกจากชุดของค่าต่อคีย์การสืบค้นสำหรับชุดโดยคีย์และคู่คีย์/ชุดซ้ำ
อะแดปเตอร์นามธรรมเฉพาะของกลไกการจัดเก็บข้อมูลพื้นฐานจากตรรกะบริการเพื่ออำนวยความสะดวกในการแลกเปลี่ยนเทคโนโลยีการจัดเก็บข้อมูลหนึ่งสำหรับอีก ค่าของสิ่งที่เป็นนามธรรมนี้คือการจัดหาเส้นทางการอัพเกรดที่ง่ายขึ้นเนื่องจากทางเลือกการจัดเก็บที่ดีขึ้นเกิดขึ้นและเพื่อให้มีตัวเลือกความยืดหยุ่นที่ยืดหยุ่นได้
ตัวอย่างเช่นบริการอาจเริ่มต้นเป็นเซิร์ฟเวอร์แอพเดียวที่มีอะแดปเตอร์ที่ห่ออินสแตนซ์ MySQL บนเซิร์ฟเวอร์เดียวกัน เมื่อความสามารถในการปรับขนาดความล้มเหลวและความต้องการประสิทธิภาพเพิ่มขึ้นเราอาจสลับอะแดปเตอร์สำหรับหนึ่งที่ห่ออินสแตนซ์ Redis ที่ยังคงมีอยู่และจำลองข้อมูลของมันในหลายเซิร์ฟเวอร์ ข้อมูลเฉพาะของวิธีการจัดเก็บข้อมูลแคชและ/หรือทำซ้ำจะโปร่งใสไปยังบริการแอนนาแกรม
เซิร์ฟเวอร์ Anagram จัดส่งด้วยหน่วยความจำ ( adapters/MemoryAdapter.js
) ซึ่งใช้แผนที่ของ JavaScript เพื่อจัดเก็บและสอบถามข้อมูล อะแดปเตอร์นี้มีแอปพลิเคชั่นที่ จำกัด เนื่องจากไม่ได้ให้ประโยชน์ของการคงอยู่ในเซิร์ฟเวอร์รีสตาร์ท แต่ทำหน้าที่เป็นรากฐานที่ดีสำหรับการทดสอบและแสดงคุณสมบัติเซิร์ฟเวอร์แอนนาแกรม
โครงการกำหนดอินเทอร์เฟซสำหรับการใช้อะแดปเตอร์ในไฟล์ adapters/adapter-template.js
ไฟล์นี้สามารถใช้เป็นหม้อต้มในการกำหนดอะแดปเตอร์ใหม่
อินเทอร์เฟซอะแดปเตอร์นั้นใช้สัญญาเนื่องจาก APIs สำหรับเทคโนโลยีการจัดเก็บมักจะเป็นแบบอะซิงโครนัส ในทางทฤษฎีนี้จะเพิ่มเวลาตอบสนองเนื่องจากสัญญาได้รับการแก้ไขผ่านคิวเหตุการณ์ แต่เอฟเฟกต์นี้เล็กน้อยภายในขอบเขตของคำขอเครือข่าย
การทำธุรกรรม
วิธี add()
และ delete()
ของอะแดปเตอร์ต้องการร้านค้าพื้นฐานเพื่อสนับสนุนการทำธุรกรรมเนื่องจากตรรกะของพวกเขาเกี่ยวข้องกับการสืบค้นข้อมูลจากนั้นทำงานในร้านค้าตามผลลัพธ์ของการสืบค้น
การโคลนนิ่งผลลัพธ์
MemoryAdapter get()
และ each()
กลับมาที่อาร์เรย์ค่าแผนที่โดยตรงไปยัง AnagramService สิ่งนี้ต้องใช้ความขยันในนามของรหัส Anagramservice เพื่อหลีกเลี่ยงการกลายพันธุ์โดยไม่ตั้งใจของผลลัพธ์ที่ได้รับการตกแต่งโดยวิธีการเหล่านี้
การโคลนนิ่งผลลัพธ์ภายในหน่วยความจำก่อนที่จะกลับมาเป็นขั้นตอนที่ชาญฉลาดในการบรรเทาข้อบกพร่องในอนาคตทำให้มั่นใจได้ว่าการเชื่อมต่อความสอดคล้องและการทำให้เกิดความประหลาดใจน้อยที่สุดกับผู้บริโภค แต่ยังเกี่ยวข้องกับค่าใช้จ่ายเพิ่มเติม
Anagramservice เป็นคลาสที่ให้ตรรกะทางธุรกิจสำหรับเซิร์ฟเวอร์ Anagram มันต้องการอินสแตนซ์ของอะแดปเตอร์ที่จะส่งผ่านไปยังตัวสร้าง
คลาส anagramservice รักษาคำและ anagram นับและใช้วิธีการที่รองรับ REST API โดยตรง
ชั้นเรียนนี้อาศัยอยู่ใน AnagramService.js
server.js
ส่งออกฟังก์ชั่นเดียว startServer()
ที่สร้างเซิร์ฟเวอร์ REST (ผ่านการกู้คืน) และสร้างอินสแตนซ์ anagramservice
startServer()
ต้องใช้อินสแตนซ์อะแดปเตอร์และยอมรับหมายเลขพอร์ตที่ต้องการคำขอบริการและเส้นทางเสริมไปยังไฟล์ข้อความเพื่อเตรียมพจนานุกรมจาก
เนื้อของ server.js
เป็นชุดของฟังก์ชั่นการตอบสนองของเซิร์ฟเวอร์ที่แยกวิเคราะห์คำขอ HTTP แต่ละรายการเรียกใช้วิธีการ anagramservice ที่เกี่ยวข้องและการตอบกลับออกด้วยการห่อวัตถุที่เหมาะสมและรหัสการตอบกลับ HTTP
app.js
เป็นจุดเข้าสำหรับเซิร์ฟเวอร์ Anagram มันเป็นไฟล์ง่าย ๆ ที่ระบุอะแดปเตอร์เพื่อเรียกใช้บริการด้วยและแหล่งข้อมูลเพิ่มเติมที่เป็นตัวเลือก
นี่เป็นไฟล์เดียวที่ต้องเปลี่ยนเมื่อสลับอะแดปเตอร์ตัวหนึ่งสำหรับไฟล์อื่น
app.js
เวอร์ชันปัจจุบันเรียกใช้ Anagramserver ด้วย MemoryAdapter และ Preloads dictionary.txt
เมื่อเริ่มต้น
ด้านล่างนี้เป็นแนวคิดบางประการสำหรับการพัฒนาเซิร์ฟเวอร์แอนนาแกรมต่อไป
GET /anagrams/:word.json
ส่งคืนอาร์เรย์ JSON ของคำที่เป็นแอนนาแกรมของคำที่ส่งผ่านใน URL
หากคำที่ผ่านมานั้นไม่ใช่คำที่รู้จัก (เช่นไม่ใช่ในพจนานุกรม) อาร์เรย์ที่ว่างเปล่าจะถูกส่งคืน (แม้ว่าแอนนาแกรมที่รู้จักสามารถเกิดขึ้นได้จากคำที่ผ่านมา)
เพื่อความสะดวกคำที่ส่งผ่านเป็นตัวพิมพ์เล็กจะตรงกับรูปแบบคำนามที่เหมาะสม
ตัวอย่าง:
$ 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>
ส่งคืนอาร์เรย์ JSON ของคำที่เป็นแอนนาแกรมของคำที่ส่งผ่านใน URL แต่ จำกัด จำนวนผลลัพธ์ที่ส่งคืน
ตัวอย่าง:
$ 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
ส่งคืนอาร์เรย์ JSON ของคำที่เป็นแอนนาแกรมของคำที่ส่งผ่านใน URL รวมถึงคำอินพุตเอง
คำที่ป้อนเข้าไม่ได้รวมอยู่ในผลลัพธ์ ANAGRAM เนื่องจากคำไม่ได้ถูกพิจารณาว่าเป็นแอนนาแกรมของตัวเอง
$ 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
ส่งคืนอาร์เรย์ JSON ของคำที่เป็นแอนนาแกรมของคำที่ส่งผ่านใน URL โดยไม่ต้องใช้คำนามที่เหมาะสม
คำนามที่เหมาะสมมักจะรวมอยู่ในผลลัพธ์ anagram
$ 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>
ส่งคืนชุดแอนนาแกรมทั้งหมดที่มี cardinality ขั้นต่ำและ/หรือสูงสุด (จำนวน anagrams ในชุด)
อาจละเว้น cardinalitymin หรือ cardinalitymax
ตัวอย่าง:
$ 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>
ส่งคืนชุด Anagram ทั้งหมดที่มีความยาวขั้นต่ำและ/หรือความยาวสูงสุด
อาจละเว้นความยาวหรือ lengthmax
ตัวอย่าง:
$ 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
ส่งคืนชุดแอนนาแกรมทั้งหมดด้วย cardinality สูงสุด
ตัวอย่าง:
$ 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
ส่งคืนชุด Anagram ทั้งหมดด้วยความยาวคำสูงสุด
ตัวอย่าง:
$ 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>
ตรวจสอบว่าชุดคำเป็นแอนนาแกรมของกันและกันหรือไม่
คำที่ผ่านทั้งหมดจะต้องเป็นที่รู้จัก (เช่นในพจนานุกรม) เพื่อให้สิ่งนี้เป็นจริง
ตัวอย่าง:
$ 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 นับเท่านั้น ชุดแอนนาแกรมแต่ละชุดในพจนานุกรมจะเพิ่ม N-1 ในการนับนี้โดยที่ n คือจำนวนของแอนนาแกรมในชุด
ตัวอย่าง:
$ curl -i "http://localhost:3000/anagrams?count=true"
HTTP/1.1 200 OK
Content-Type: application/json
...
{ "counts": { "anagram": 20043 }}
GET /words?count=true
ส่งคืนจำนวนคำในพจนานุกรม
ตัวอย่าง:
$ curl -i "http://localhost:3000/words?count=true"
HTTP/1.1 200 OK
Content-Type: application/json
...
{ "counts": { "word": 235886 }}
GET /words?stats=true
ส่งคืนสถิติบางอย่างเกี่ยวกับคำในพจนานุกรม
ตัวอย่าง:
$ 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
ใช้คำศัพท์ JSON และเพิ่มลงในพจนานุกรม
ตัวอย่าง:
$ 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
ลบคำเดียวจากพจนานุกรม
หากคำที่ผ่านมานั้นไม่ใช่คำที่รู้จัก (เช่นไม่ใช่ในพจนานุกรม) จะส่งคืน 404
ตัวอย่าง:
$ curl -i -X DELETE "http://localhost:3000/words/care.json"
HTTP/1.1 204 No Content
...
DELETE /words/:word.json?includeAnagrams=true
ลบคำเดียว และแอนนาแกรมทั้งหมด ออกจากพจนานุกรม
หากคำที่ผ่านมานั้นไม่ใช่คำที่รู้จัก (เช่นไม่ใช่ในพจนานุกรม) จะไม่มีการลบและส่งคืน 404
ตัวอย่าง:
$ curl -i -X DELETE "http://localhost:3000/words/acre.json?includeAnagrams=true"
HTTP/1.1 204 No Content
...
DELETE /words.json
ล้างเนื้อหาทั้งหมดจากพจนานุกรม
ตัวอย่าง:
$ curl -i -X DELETE "http://localhost:3000/words.json"
HTTP/1.1 204 No Content
...