Anagram Server는 Node.js 기반 응용 프로그램으로, 단어 사전에 대해 Anagram 관련 검색을 수행하기위한 REST 기반 API를 노출시킵니다. 주요 기능은 주어진 단어에 대해 알려진 아나그램을 찾는 것입니다.
또한 아나그램 세트 (서로의 아나그램 인 단어 그룹)는 카디널리티 (세트의 단어 수) 또는 단어 길이에 의해 쿼리 될 수 있습니다. 주어진 단어 세트가 아나그램 세트를 구성하는지 여부를 쿼리 할 수도 있습니다.
아나그램을 쿼리 할 수있는 단어 사전을 API를 통해 추가, 삭제 또는 완전히 지우실 수 있습니다. 메모리 전용 서비스 (즉, 서비스 재시작에 따라 변경되지 않음)로 구성되면 Anagram 서버는 시작시 표준 영어 단어 세트를 예방합니다 ( app.js
참조).
마지막으로,로드 된 사전에 대한 여러 통계는 API를 통해 쿼리 할 수 있습니다.
필요한 경우 Node.js를 설치하십시오
NPM 종속성을 설치하십시오
npm install
npm start
기본적으로 앱은 포트 3000에 대한 요청을 제공합니다.이를 재정의하려면 package.json
의 시작 스크립트를 업데이트하여 대체 포트 번호를 노드 명령으로 전달할 수 있습니다. 예를 들어:
"start": "node src/app.js -p 8080"
효과적인 포트에서 들어오는 트래픽을 명시 적으로 허용해야 할 수도 있습니다. 예를 들어, 다음 재부팅까지 Linux에서 Port 3000을 엽니 다.
sudo iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 3000 -j ACCEPT
필요한 경우 Docker를 설치하십시오
Docker 이미지를 작성하십시오
sudo docker build -t anagram-server .
sudo docker run -p 3000:3000 anagram-server
대체 호스트 포트 (예 : -p 8080:3000
)에 매핑하는 것이 좋습니다.
아나그램 서버는 루비 테스트 스크립트와 함께 제공됩니다.
기본적으로 Anagram 서버는 시작시 dictionary.txt
에서 단어를 예압합니다.
테스트 스크립트는 소스 패키지의 test
하위 폴더에 있으며 개별적으로 실행할 수 있습니다.
ruby anagram_test.rb
ruby anagram_test_2.rb
Anagram 서버는 cURL
또는 Postman과 같은 도구로 수동으로 테스트 할 수 있습니다. 예를 들어 (앱 호스트의 새 터미널 창의 명령 줄에서) :
curl -i "http://localhost:3000/anagrams/shout.json"
기본적으로 Anagram 서버는 시작시 dictionary.txt
에서 단어를 예압하므로 테스트하기 전에 다음 명령으로 사전을 지우려면 다음과 같습니다.
curl -i -X DELETE "http://localhost:3000/words.json"
원격 테스트의 경우 "LocalHost"를 anagram_client.rb
의 앱 호스트 IP로 바꾸고이 문서의 샘플 명령으로 바꾸십시오.
또한 기본값 (3000) 이외의 포트로 Anagram 서버를 실행하는 경우 anagram_client.rb
및 샘플 명령에서 포트 번호를 업데이트하십시오.
대문자와 소문자 영어 알파벳 문자 또는 하이픈의 조합이 포함 된 경우 단어가 유효한 것으로 간주됩니다. 유효한 단어는 하이픈으로 시작 하거나 끝나지 않을 수 있습니다.
잘못된 단어를 얻거나 삭제하려고 시도하면 400 Bad Request
발생합니다.
유효하지 않은 단어를 게시하려고 시도하면 204 No Content
.
적절한 명사는 첫 글자 (대문자 임)를 제외한 모든 소문자와 하이픈 (대문자 또는 소문자 일 수 있음)을 제외한 모든 소문자가있는 단어로 간주됩니다.
몇 가지 예는 영어, Zulu, Jean-Christophe입니다
적절한 명사는 소문자 버전과 구별되는 것으로 간주됩니다. 예를 들어, Abigail 과 Abigail 은 두 개의 독특한 단어 (및 서로의 아나그램)입니다.
명시 적으로 제외되지 않는 한 적절한 명사는 항상 결과에 포함됩니다 ( GET /anagrams/:word.json
의 excludeProperNouns
Parm 참조).
편의를 위해 Anagram Server를 사용하면 경우에 따라 적절한 명사를 소문자와 일치시킬 수 있습니다. 예를 들어, 아나그램을 쿼리 할 때 :
$ curl -i "http://localhost:3000/anagrams/aaru.json?includeInput=true"
HTTP/1.1 200 OK
Content-Type: application/json
...
{ "anagrams": [
"Aaru",
"aura"]
}
Anagram 서버 아키텍처는 4 개의 레이어로 구성됩니다 (가장 낮은 수준에서 가장 높은).
어댑터는 Anagram 서버에서 사용하는 기본 저장 별 쿼리, 반복 및 CRUD 작업을 제공하는 클래스입니다. 구체적으로, 어댑터는 키 문자열을 일련의 값과 연관시키고 키 당 값 세트에서 추가 및 삭제, 키에 의한 쿼리 및 키/세트 쌍을 반복하기위한 의미론을 제공합니다.
어댑터는 하나의 스토리지 기술을 다른 스토리지 기술로 바꾸는 것을 용이하게하기 위해 서비스 논리에서 기본 스토리지 메커니즘의 세부 사항을 추상화합니다. 이 추상화의 가치는보다 유리한 스토리지 대안이 등장 할 때 쉽게 업그레이드 된 경로를 제공하고 유연한 확장 성 옵션을 제공하는 것입니다.
예를 들어, 서비스는 처음에 동일한 서버에서 MySQL 인스턴스를 랩핑하는 어댑터가있는 단일 앱 서버로 롤아웃 할 수 있습니다. 확장 성, 장애 조치 및 성능 요구가 증가함에 따라 여러 서버에서 데이터를 지속하고 복제하는 Redis 인스턴스를 랩핑하는 어댑터를 교체 할 수 있습니다. 데이터가 저장, 캐시 및/또는 복제 된 방법에 대한 세부 사항은 아나그램 서비스에 투명합니다.
Anagram Server는 JavaScript의 맵을 사용하여 데이터를 저장하고 쿼리하는 MemoryAdapter ( adapters/MemoryAdapter.js
)와 함께 제공됩니다. 이 어댑터는 서버 재시작 전반에 걸쳐 지속성의 이점을 제공하지 않기 때문에 응용 프로그램이 제한되어 있지만 Anagram 서버 기능을 테스트하고 보여주는 좋은 기초가됩니다.
이 프로젝트는 파일 adapters/adapter-template.js
에서 어댑터를 구현하기위한 인터페이스를 정의합니다. 이 파일은 새 어댑터를 정의 할 때 보일러 플레이트로 사용할 수 있습니다.
스토리지 기술에 대한 API가 비동기식이기 때문에 어댑터 인터페이스는 약속 기반입니다. 이론적으로 이것은 약속이 이벤트 큐를 통해 해결되기 때문에 응답 시간을 추가하지만,이 효과는 네트워크 요청의 범위 내에서 무시할 수 있습니다.
업무
어댑터의 add()
및 delete()
메소드는 논리가 데이터를 쿼리하고 쿼리 결과를 기반으로 스토어에서 작동하기 때문에 기본 저장소가 트랜잭션을 지원해야합니다.
복제 결과
MemoryAdapter get()
및 each()
메소드는 맵 값 배열을 Anagramservice에 직접 반환합니다. 이는 이러한 방법에 의해 제공된 결과의 우발적 인 돌연변이를 피하기 위해 Anagramservice 코드를 대신하여 근면이 필요합니다.
MemoryAdapter에서 결과를 복제하기 전에 MemoryAdapter 내에서 결과를 복제하는 것은 미래 버그를 완화하고 인터페이스 일관성을 보장하며 소비자에게 놀라운 놀라움을 줄 수있는 현명한 단계가 될 것입니다.
Anagramservice는 Anagram 서버의 비즈니스 로직을 제공하는 클래스입니다. 어댑터 인스턴스를 생성자에게 전달해야합니다.
Anagramservice 클래스는 Word 및 Anagram Counts를 유지하고 REST API를 직접 지원하는 방법을 구현합니다.
이 클래스는 AnagramService.js
에 살고 있습니다.
server.js
Restify를 통해 RESTIFY를 생성하는 단일 함수 startServer()
내보내고 AnagramService를 인스턴스화합니다.
startServer()
어댑터 인스턴스가 필요하며 선택적으로 서비스 요청에 대한 포트 번호와 텍스트 파일로의 선택적 경로를 수락하여 사전을 미리 채색합니다.
server.js
의 고기는 개별 HTTP 요청을 구문 분석하고 관련 Anagramservice 메소드를 호출하고 적절한 객체 랩핑 및 HTTP 응답 코드로 응답을 발행하는 서버 응답 기능 세트입니다.
app.js
Anagram 서버의 진입 점입니다. 서비스를 실행하기 위해 어댑터를 지정하고 선택적 데이터 예압 소스를 지정하는 간단한 파일입니다.
이것은 한 어댑터를 다른 어댑터로 바꿀 때 변경 해야하는 유일한 파일입니다.
app.js
의 현재 버전은 시작시 MemoryAdapter 및 preloads dictionary.txt
로 Anagramserver를 실행합니다.
다음은 아나그램 서버를 추가로 개발하기위한 몇 가지 아이디어입니다.
GET /anagrams/:word.json
URL에 전달 된 단어의 아나그램 인 JSON 배열을 반환하십시오.
통과 된 단어 자체가 알려진 단어가 아닌 경우 (즉, 사전이 아닌) 빈 배열이 반환됩니다 (알려진 아나그램이 전달 된 단어에서 형성 될 수있는 경우에도).
편의를 위해 소문자로 전달 된 단어는 적절한 명사 형태와 일치합니다.
예:
$ 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>
URL에 전달 된 단어의 아나그램 인 JSON 배열을 반환 하지만 반환 된 결과 수를 제한하십시오 .
예:
$ 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
입력 단어 자체를 포함하여 URL에 전달 된 단어의 아나그램 인 JSON 배열을 반환하십시오.
입력 단어는 일반적으로 아나 그램 결과에 포함되지 않습니다. 단어는 일반적으로 아나그램 자체로 간주되지 않기 때문입니다.
$ 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
URL에 전달 된 단어의 아나그램 인 JSON 배열을 반환하여 적절한 명사를 생략하십시오 .
적절한 명사는 일반적으로 아나그램 결과에 포함됩니다.
$ 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>
최소 및/또는 최대 카디널리티가있는 모든 아나그램 세트 (세트의 아나그램 수)를 반환하십시오.
추기경 민족 또는 카디 큘랑 맥맥은 생략 될 수 있습니다.
예 :
$ 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>
최소 및/또는 최대 단어 길이가있는 모든 아나그램 세트를 반환하십시오.
길이 민족 또는 길이 max를 생략 할 수 있습니다.
예:
$ 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
모든 아나그램 세트를 최대 카디널리티로 반환하십시오.
예:
$ 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
최대 단어 길이로 모든 아나그램 세트를 반환하십시오.
예:
$ 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
아나그램 수를 반환합니다. 사전의 각 아나그램 세트는 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
...