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
parent
4333d4fcc3
commit
013fef0f0d
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
});
|
||||
|
|
|
@ -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[]
|
||||
);`);
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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 England’s Emerging Colonial Empire, 1601–1698" "{""(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)""}"
|
|
@ -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",
|
||||
|
|
|
@ -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"
|
||||
},
|
||||
|
|
|
@ -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" });
|
||||
}
|
||||
});
|
||||
|
||||
|
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue