OAP-38: Add /ngrams endpoint to API (#19)

* Added data function to query ngrams within the api

* removed cleaning and seeding tasks from API level, handled at engine level

* Added /:handle/ngrams endpoint to API routes

* Reflected change from uuid to handle in log messages within API

* Just some API readme changes

* Added regex to routes to mitigate url decoding, plus added validation function for handle

Co-authored-by: j-sofia <joey.sofia1@gmail.com>
Co-authored-by: Peter Rauscher <peterrauscher@protonmail.com>

Co-authored-by: j-sofia <joey.sofia1@gmail.com>
fix-build-job
Peter Rauscher 2022-11-09 23:45:48 +00:00 committed by GitHub
parent 4333d4fcc3
commit 013fef0f0d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 336 additions and 53 deletions

View File

@ -20,16 +20,21 @@ DATABASE_URL="postgres://postgres:password@localhost:5432/postgres"
PORT=3001
```
To populate the database with seed data, run `make setup-env` from `oapen-engine/`
## Running with npm
```
npm ci
npm run clean
npm start
```
Endpoint: /GET http://localhost:3001/api/{item_uuid}
## Endpoints
e.g. http://localhost:3001/api/a91a6b7d-874a-4144-b44d-0da647a82acc
- `Endpoint: /GET http://localhost:3001/api/{handle}`
To populate the database with seed data, run `make setup-env` from `oapen-engine/`
- e.g. http://localhost:3001/api/20.400.12657/47581
- `Endpoint: /GET http://localhost:3001/api/{handle}/ngrams`
- e.g. http://localhost:3001/api/20.400.12657/47581/ngrams

View File

@ -17,5 +17,6 @@ const port = process.env.PORT || 3001;
app.listen(port, () => {
console.log("Suggestion Service API is up on port " + port);
console.log("Endpoint: /GET http://localhost:" + port + "/api/{item_uuid}");
console.log("Endpoint: /GET http://localhost:" + port + "/api/{handle}");
console.log("Endpoint: /GET http://localhost:" + port + "/api/{handle}/ngrams")
});

View File

@ -1,17 +0,0 @@
require("dotenv").config({ path: "./db/database.env" });
const db = require("./connection.js");
db.none(`
DROP SCHEMA IF EXISTS oapen_suggestions CASCADE;
DROP TABLE IF EXISTS suggestions CASCADE;
DROP TYPE IF EXISTS suggestion CASCADE;
`);
db.none(`
CREATE TYPE suggestion AS (id uuid, rank int);
CREATE SCHEMA oapen_suggestions
CREATE TABLE IF NOT EXISTS suggestions (
item_id uuid PRIMARY KEY,
name text,
suggestions suggestion[]
);`);

View File

@ -3,10 +3,20 @@ const { ParameterizedQuery: PQ } = require("pg-promise");
const db = require("./connection.js");
async function querySuggestions(id) {
await validate.checkHandle(id);
async function querySuggestions(handle) {
await validate.checkHandle(handle);
const query = new PQ({ text: "SELECT * FROM oapen_suggestions.suggestions WHERE item_id = $1", values: [id] });
const query = new PQ({ text: "SELECT * FROM oapen_suggestions.suggestions WHERE handle = $1", values: [handle] });
return db.one(query).catch((error) => {
return { error: { name: error.name, message: error.message } };
});
}
async function queryNgrams(handle) {
await validate.checkHandle(handle);
const query = new PQ({ text: "SELECT * FROM oapen_suggestions.ngrams WHERE handle = $1", values: [handle] });
return db.one(query).catch((error) => {
return { error: { name: error.name, message: error.message } };
@ -15,4 +25,5 @@ async function querySuggestions(id) {
module.exports = {
querySuggestions,
queryNgrams,
};

View File

@ -1,14 +0,0 @@
require("dotenv").config({ path: "./db/database.env" });
const db = require("./connection.js");
//seed can be run from "make setup-env" from oapen-engine/
//"7b5fdf5b-9ffa-4073-84fe-c21cce0025b5" "Energy Poverty, Practice, and Policy" "{""(7b5fdf5b-9ffa-4073-84fe-c21cce0025b5,0)""}"
//"a91a6b7d-874a-4144-b44d-0da647a82acc" "The Future European Energy System" "{""(a91a6b7d-874a-4144-b44d-0da647a82acc,1)""}"
//"858df59f-0014-4355-8435-dca9c187ce0c" "Literatura latinoamericana mundial" "{""(858df59f-0014-4355-8435-dca9c187ce0c,2)""}"
//"44c40c47-df67-476a-9603-3054f726b156" "Religion and Governance in Englands Emerging Colonial Empire, 16011698" "{""(44c40c47-df67-476a-9603-3054f726b156,3)""}"
//"2ce07264-58ac-426a-9c88-500f8b47e7f5" "Open Science: the Very Idea" "{""(2ce07264-58ac-426a-9c88-500f8b47e7f5,4)""}"
//"4ba6ae5d-1797-4def-b0d7-1cd8652e5cd9" "Embodying Contagion" "{""(4ba6ae5d-1797-4def-b0d7-1cd8652e5cd9,5)""}"
//"57753423-cb8a-4f08-815d-ac7aa19b049b" "Thou Shalt Forget" "{""(57753423-cb8a-4f08-815d-ac7aa19b049b,6)""}"
//"7df13adb-771b-4d66-b081-2345059622bc" "Engines of Order" "{""(7df13adb-771b-4d66-b081-2345059622bc,7)""}"
//"ae797d93-6c5e-46ee-a193-45cd7c114e65" "Atlas" "{""(ae797d93-6c5e-46ee-a193-45cd7c114e65,8)""}"
//"8e001ebf-5e63-44f5-9f31-5d79389e0f14" "Vulnerable" "{""(8e001ebf-5e63-44f5-9f31-5d79389e0f14,9)""}"

283
api/package-lock.json generated
View File

@ -7,11 +7,13 @@
"": {
"name": "oapen-suggestion-service-api",
"version": "0.0.1",
"license": "ISC",
"license": "../LICENSE.md",
"dependencies": {
"dotenv": "^16.0.3",
"express": "^4.18.1",
"node-watch": "^0.7.3",
"nodemon": "^2.0.20"
"nodemon": "^2.0.20",
"pg-promise": "^10.12.0"
}
},
"node_modules/abbrev": {
@ -48,6 +50,14 @@
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
},
"node_modules/assert-options": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/assert-options/-/assert-options-0.7.0.tgz",
"integrity": "sha512-7q9uNH/Dh8gFgpIIb9ja8PJEWA5AQy3xnBC8jtKs8K/gNVCr1K6kIvlm59HUyYgvM7oEDoLzGgPcGd9FqhtXEQ==",
"engines": {
"node": ">=8.0.0"
}
},
"node_modules/balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@ -104,6 +114,14 @@
"node": ">=8"
}
},
"node_modules/buffer-writer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz",
"integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==",
"engines": {
"node": ">=4"
}
},
"node_modules/bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@ -667,6 +685,102 @@
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
},
"node_modules/pg": {
"version": "8.8.0",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.8.0.tgz",
"integrity": "sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==",
"dependencies": {
"buffer-writer": "2.0.0",
"packet-reader": "1.0.0",
"pg-connection-string": "^2.5.0",
"pg-pool": "^3.5.2",
"pg-protocol": "^1.5.0",
"pg-types": "^2.1.0",
"pgpass": "1.x"
},
"engines": {
"node": ">= 8.0.0"
},
"peerDependencies": {
"pg-native": ">=3.0.1"
},
"peerDependenciesMeta": {
"pg-native": {
"optional": true
}
}
},
"node_modules/pg-connection-string": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz",
"integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ=="
},
"node_modules/pg-int8": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
"engines": {
"node": ">=4.0.0"
}
},
"node_modules/pg-minify": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/pg-minify/-/pg-minify-1.6.2.tgz",
"integrity": "sha512-1KdmFGGTP6jplJoI8MfvRlfvMiyBivMRP7/ffh4a11RUFJ7kC2J0ZHlipoKiH/1hz+DVgceon9U2qbaHpPeyPg==",
"engines": {
"node": ">=8.0"
}
},
"node_modules/pg-pool": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.2.tgz",
"integrity": "sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w==",
"peerDependencies": {
"pg": ">=8.0"
}
},
"node_modules/pg-promise": {
"version": "10.12.1",
"resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-10.12.1.tgz",
"integrity": "sha512-SiJkBUDGq7PNfJFJbWferodsSH+vLrhte0Q0kVgQbwlNYeKmp9Hhkr+357+5DWEuBGOHhSu1UQffSSf5HVqRtA==",
"dependencies": {
"assert-options": "0.7.0",
"pg": "8.8.0",
"pg-minify": "1.6.2",
"spex": "3.2.0"
},
"engines": {
"node": ">=12.0"
}
},
"node_modules/pg-protocol": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz",
"integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ=="
},
"node_modules/pg-types": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
"dependencies": {
"pg-int8": "1.0.1",
"postgres-array": "~2.0.0",
"postgres-bytea": "~1.0.0",
"postgres-date": "~1.0.4",
"postgres-interval": "^1.1.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/pgpass": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
"integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
"dependencies": {
"split2": "^4.1.0"
}
},
"node_modules/picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
@ -678,6 +792,41 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/postgres-array": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
"engines": {
"node": ">=4"
}
},
"node_modules/postgres-bytea": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
"integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/postgres-date": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/postgres-interval": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
"dependencies": {
"xtend": "^4.0.0"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@ -853,6 +1002,22 @@
"semver": "bin/semver.js"
}
},
"node_modules/spex": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/spex/-/spex-3.2.0.tgz",
"integrity": "sha512-9srjJM7NaymrpwMHvSmpDeIK5GoRMX/Tq0E8aOlDPS54dDnDUIp30DrP9SphMPEETDLzEM9+4qo+KipmbtPecg==",
"engines": {
"node": ">=4.5"
}
},
"node_modules/split2": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz",
"integrity": "sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ==",
"engines": {
"node": ">= 10.x"
}
},
"node_modules/statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
@ -981,6 +1146,11 @@
"resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
"integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg=="
},
"assert-options": {
"version": "0.7.0",
"resolved": "https://registry.npmjs.org/assert-options/-/assert-options-0.7.0.tgz",
"integrity": "sha512-7q9uNH/Dh8gFgpIIb9ja8PJEWA5AQy3xnBC8jtKs8K/gNVCr1K6kIvlm59HUyYgvM7oEDoLzGgPcGd9FqhtXEQ=="
},
"balanced-match": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
@ -1027,6 +1197,11 @@
"fill-range": "^7.0.1"
}
},
"buffer-writer": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz",
"integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw=="
},
"bytes": {
"version": "3.1.2",
"resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@ -1434,11 +1609,105 @@
"resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
"integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ=="
},
"pg": {
"version": "8.8.0",
"resolved": "https://registry.npmjs.org/pg/-/pg-8.8.0.tgz",
"integrity": "sha512-UXYN0ziKj+AeNNP7VDMwrehpACThH7LUl/p8TDFpEUuSejCUIwGSfxpHsPvtM6/WXFy6SU4E5RG4IJV/TZAGjw==",
"requires": {
"buffer-writer": "2.0.0",
"packet-reader": "1.0.0",
"pg-connection-string": "^2.5.0",
"pg-pool": "^3.5.2",
"pg-protocol": "^1.5.0",
"pg-types": "^2.1.0",
"pgpass": "1.x"
}
},
"pg-connection-string": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.5.0.tgz",
"integrity": "sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ=="
},
"pg-int8": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw=="
},
"pg-minify": {
"version": "1.6.2",
"resolved": "https://registry.npmjs.org/pg-minify/-/pg-minify-1.6.2.tgz",
"integrity": "sha512-1KdmFGGTP6jplJoI8MfvRlfvMiyBivMRP7/ffh4a11RUFJ7kC2J0ZHlipoKiH/1hz+DVgceon9U2qbaHpPeyPg=="
},
"pg-pool": {
"version": "3.5.2",
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.5.2.tgz",
"integrity": "sha512-His3Fh17Z4eg7oANLob6ZvH8xIVen3phEZh2QuyrIl4dQSDVEabNducv6ysROKpDNPSD+12tONZVWfSgMvDD9w==",
"requires": {}
},
"pg-promise": {
"version": "10.12.1",
"resolved": "https://registry.npmjs.org/pg-promise/-/pg-promise-10.12.1.tgz",
"integrity": "sha512-SiJkBUDGq7PNfJFJbWferodsSH+vLrhte0Q0kVgQbwlNYeKmp9Hhkr+357+5DWEuBGOHhSu1UQffSSf5HVqRtA==",
"requires": {
"assert-options": "0.7.0",
"pg": "8.8.0",
"pg-minify": "1.6.2",
"spex": "3.2.0"
}
},
"pg-protocol": {
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.5.0.tgz",
"integrity": "sha512-muRttij7H8TqRNu/DxrAJQITO4Ac7RmX3Klyr/9mJEOBeIpgnF8f9jAfRz5d3XwQZl5qBjF9gLsUtMPJE0vezQ=="
},
"pg-types": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
"requires": {
"pg-int8": "1.0.1",
"postgres-array": "~2.0.0",
"postgres-bytea": "~1.0.0",
"postgres-date": "~1.0.4",
"postgres-interval": "^1.1.0"
}
},
"pgpass": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
"integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
"requires": {
"split2": "^4.1.0"
}
},
"picomatch": {
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
},
"postgres-array": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA=="
},
"postgres-bytea": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz",
"integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w=="
},
"postgres-date": {
"version": "1.0.7",
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q=="
},
"postgres-interval": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
"requires": {
"xtend": "^4.0.0"
}
},
"proxy-addr": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@ -1568,6 +1837,16 @@
}
}
},
"spex": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/spex/-/spex-3.2.0.tgz",
"integrity": "sha512-9srjJM7NaymrpwMHvSmpDeIK5GoRMX/Tq0E8aOlDPS54dDnDUIp30DrP9SphMPEETDLzEM9+4qo+KipmbtPecg=="
},
"split2": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/split2/-/split2-4.1.0.tgz",
"integrity": "sha512-VBiJxFkxiXRlUIeyMQi8s4hgvKCSjtknJv/LVYbrgALPwf5zSKmEwV9Lst25AkvMDnvxODugjdl6KZgwKM1WYQ=="
},
"statuses": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",

View File

@ -4,8 +4,6 @@
"description": "An API which allows you to search for books with similar content from the oapen.org library.",
"main": "app.js",
"scripts": {
"clean": "node ./db/clean.js",
"seed": "node ./db/seed.js",
"dev": "nodemon ./app.js",
"start": "node app.js"
},

View File

@ -1,11 +1,12 @@
const express = require("express");
const router = express.Router();
const validate = require("./validate");
const pgp = require("pg-promise");
const validate = require("./validate");
const data = require("./db/data.js");
//GET endpoint
router.get("/:handle", async (req, res) => {
//GET endpoint for suggestions
router.get("/:handle([0-9]+.[0-9]+.[0-9]+/[0-9]+)", async (req, res) => {
try {
var handle = req.params.handle;
await validate.checkHandle(handle);
@ -13,16 +14,34 @@ router.get("/:handle", async (req, res) => {
let responseData = await data.querySuggestions(handle);
if (responseData.error && responseData.error.name === pgp.errors.QueryResultError.name) {
res.status(404).json({ error: responseData.error.message });
return;
return res.status(404).json({ error: responseData.error.message });
} else if (responseData.error) {
res.status(500).json(responseData);
return;
return res.status(500).json(responseData);
}
res.status(200).json(responseData);
return res.status(200).json(responseData);
} catch (e) {
res.status(500).json({ error: "Internal server error" });
return res.status(500).json({ error: "Internal server error" });
}
});
//GET endpoint for ngrams
router.get('/:handle([0-9]+.[0-9]+.[0-9]+/[0-9]+)/ngrams', async (req, res) => {
try {
var handle = req.params.handle;
await validate.checkHandle(handle);
let responseData = await data.queryNgrams(handle);
if (responseData.error && responseData.error.name === pgp.errors.QueryResultError.name) {
return res.status(404).json({ error: responseData.error.message });
} else if (responseData.error) {
return res.status(500).json(responseData);
}
return res.status(200).json(responseData);
} catch (e) {
return res.status(500).json({ error: "Internal server error" });
}
});

View File

@ -1,5 +1,6 @@
let checkHandle = async (handle) => {
// TODO: Validate the book's handle
if (!handle || typeof handle !== "string" || !handle.trim()) throw "Invalid handle, cannot be undefined.";
if (!new RegExp('([0-9]+.[0-9]+.[0-9]+/[0-9]+)', 'g').test(handle)) throw "Invalid handle, exmaple format: 20.500.12657/47586"
return true;
};