-
Notifications
You must be signed in to change notification settings - Fork 1
Services: a bird's eye view (for dev)
Impresso Middle Layer (IML) services are based on featherjs services. This means that each request goes through the same path: identify the service and the request method, run the before hooks, perform the query, run the after hooks and if everything goes well return the results.
Services are initially configured at /src/services/<service-name>/<service-name>.service.js
. This module loads the correct class to handle the request, then initialises the hooks. Urls with /<service-name>
are then registered with their own specific service using app.use('/<service-name>')
.
For more details, see the feathersjs services docs
Following CRUD guidelines, each service class should have methods to reply to CRUD-like requests.
So, GET /<service-name>/<id>
correspond to the async get(id)
class method, POST /<service-name>
requests to the async create(params)
class method etc.
important: if a class doesn't implement a method, a http 501 Not Implemented
server error response is being trhown.
The global hooks are specified in app.hooks.js, while other hooks are registered in each service hook module.
The validate() hook is a common hook used to validate POST data and GET params, while queryWithCommonParams() verifies pagination parameters and adds the current authentified user, if any, to the current context
(as _exec_user_uid
).
IML first database is neo4j: a Neo4JService class is able to run neo4J queries based on the cypher queries specified in each service cypher file, e.g. articles.queries.cyp. We use the library decypher to get a handy object out of this file: every CRUD request name has a specific name in the cypher file.
Usually each service class extends this class functionalities. In this case, article class performs a SOLR request at the same time
class Service extends Neo4jService {
constructor(options) {
super(options);
this.solr = solr.client(options.app.get('solr'));
}
async get(id, params) {
const results = await Promise.all([
// we perform a solr request to get
// the full text, regions of the specified article
this.solr.findAll({
q: `id:${id}`,
fl: 'id,page_nb_is,title_txt_fr,content_txt_fr',
}),
// at the same time, we use the neo4jService get to get article instance from our graph db
super.get(id, params),
]);
//
if (results[0].response.numFound !== 1) {
throw new NotFound();
}
// merge the two results:
return {
...results[0].response.docs[0],
...results[1],
};
}
}
This hooks adds the correct IIIF Articles, pages and issues based on the assignIIIF()
hooks that recursively look for IIIF "candidates" and add the iiif related properties to each object: iiif endpoint iiif
, low res preview iiif_thumbnail
and iiif_fragment
for regions objects