Skip to content

Filters reference

Dmitry edited this page Dec 2, 2016 · 1 revision

Filters was introduced to make pre- and post-processing of requests and responses possible.

With filters you can validate, log, modify URL, headers, message body, etc. for all services.

Filters can be applied at phases such as:

Phase Description
Header Only message header has been read, no body (if any) is yet read
PreDispatch Full request including body has been read, not yet parsed
PreInvoke The service is going to be invoked with parsed/generated OM request
PostDispatch Request is processed by the service, response written to OM, but not to output buffer
PreSend Response body written to output buffer and going to send to client

To create own filter you must implement ngrest::Filter interface and perform filter logic. Also to deploy own filters on ngrest engine you must implement ngrest::FilterGroup interface, export it as plugin symbol, compile shared library and place it into ~/.ngrest/ngrest-build/deploy/share/ngrest/filters directory.

To stop processing message you can throw ngrest::HttpException. In this case client connection will be closed.

Example

Here is a simple filter example which reads HTTP headers and prints it to log:

MyFilter.hpp


#include <ngrest/common/HttpMessage.h>
#include <ngrest/engine/Filter.h>
#include <ngrest/utils/Log.h>

class MyFilter: public Filter
{
public:
    const std::string& getName() const override
    {
        static std::string name = "my-filter";
        return name;
    }

    const std::list<std::string>& getDependencies() const override
    {
        std::list<std::string> deps = {};
        return deps;
    }


    void filter(Phase phase, MessageContext* context) override
    {
        for (Header* header = context->request->headers; header; header = header->next)
            LogDebug() << "header: " << header->name << " : " << header->value;
    }
};


MyFilterGroup.h

#include <ngrest/engine/FilterGroup.h>

class MyFilterGroup: public ngrest::FilterGroup
{
public:
    MyFilterGroup();
    ~MyFilterGroup();
    const std::string& getName() const override;
    const FiltersMap& getFilters() const override;

private:
    FiltersMap filters;
};

MyFilterGroup.cpp

#include "MyFilter.h"
#include "MyFilterGroup.h"

NGREST_DECLARE_PLUGIN(MyFilterGroup) // export filter group

MyFilterGroup::MyFilterGroup():
  filters({
      {Phase::Header, {new MyFilter()}}
  })
{
}

MyFilterGroup::~MyFilterGroup()
{
    for (auto it : filters)
        for (Filter* filter : it.second)
            delete filter;
    filters.clear();
}

const std::string& MyFilterGroup::getName() const
{
    static const std::string name = "MyFilterGroup";
    return name;
}

const FiltersMap& MyFilterGroup::getFilters() const
{
    return filters;
}

More complex example

For a more complex filter example see https://github.com/loentar/ngrest/tree/master/tests/filters