creating a restheart MongoInterceptor

66 views Asked by At

I want to create an interceptor that takes data from the incoming request and issues a custom query to the underlying db, returning the result of that query to the user. I cannot figure out how to return the results of the custom query to the user.

Here is the example I tried, but the response document I create and set in the plugin is not being returned to the user.

Is it possible to do this using a MongoInterceptor?

@RegisterPlugin(name = "exampleInterceptor",
        description = "example interceptor",
        interceptPoint = InterceptPoint.REQUEST_AFTER_AUTH,
        priority = 100)
public class ExampleInterceptor implements MongoInterceptor {

    @Override
    public void handle(MongoRequest request, MongoResponse response)
            throws Exception
    {
        String dbName = request.getDBName();
        String collName = request.getCollectionName();
        String[] pathInfo = request.getMappedRequestUri().split("/");
        if (pathInfo.length == 3) {
            String id = pathInfo[2];
            BsonDocument doc = new BsonDocument();
            doc.put("db", new BsonString(dbName));
            doc.put("collection", new BsonString(collName));
            doc.put("id", new BsonString(id));
            response.setContent(doc);
        }
    }

    @Override
    public boolean resolve(MongoRequest request, MongoResponse response) {
        return true;
    }
}

1

There are 1 answers

3
Andrea Di Cesare On

In order to modify the response, you need interceptPoint = InterceptPoint.RESPONSE otherwise the response content will be overwritten by the MongoService

Also note that the response content can be null (for write requests), an object (for GET /coll/docid) or an array (for GET /coll), so you need to deal with different cases

Try the following:

@RegisterPlugin(name = "exampleInterceptor",
        description = "example interceptor",
        interceptPoint = InterceptPoint.RESPONSE, // <--- intercept the response
        priority = 100)
public class ExampleInterceptor implements MongoInterceptor {

    @Override
    public void handle(MongoRequest request, MongoResponse response)
    {
        String dbName = request.getDBName() == null ? "null" : request.getDBName();
        String collName = request.getCollectionName() == null ? "null": request.getCollectionName();
        BsonValue id = request.getDocumentId() == null ? BsonNull.VALUE : request.getDocumentId();

        BsonDocument responseContent;

        if (response.getContent() == null) { // null for write requests
             responseContent = new BsonDocument();
             response.setContent(responseContent);
        } else if (response.getContent().isDocument()) { // GET /coll/docid -> object
             responseContent = response.getContent().asDocument();
        } else { // GET /coll -> array
             responseContent = new BsonDocument();
             responseContent.put("docs", response.getContent());
             response.setContent(responseContent);
        }

        // add db, collection and id properties to response content
        responseContent.put("db", new BsonString(dbName));
        responseContent.put("collection", new BsonString(collName));
        responseContent.put("id", id);
    }

    @Override
    public boolean resolve(MongoRequest request, MongoResponse response) {
        return true;
    }
}