用于RESTful-API中的动态DQL的Symfony2-Bundle

I built a simple API in symfony2 with doctrine 2 (with a little help from here: http://williamdurand.fr/2012/08/02/rest-apis-with-symfony2-the-right-way/). Everything works fine. GET (All/One), PUT, POST or DELETE works, but I can either fetch all Resources or only one with a specific Id.

But I want something like this: GET /api/stuff?filter={ [ { "field": "fieldname", "operator": "eq", "value": "foo" }, { ... } ] }

and then call getByFilter($filter) to build a generic DQL. I have a pretty clear idea how to do it (I did something similar, without symfony), but I don't want to reinvent the wheel.

Are there any bundles or best practices out there?

As far as I know, there is no bundle providing generic filtering feature. What you are describing here looks a bit like OData filter system queries, and I never found a bundle implementing such a spec.

However, the FOSRestBundle provides a ParamFetcher feature, allowing you to configure the query parameters you may expect, as well as default values, and basic validation constraints. This is something to consider while developing the "filtering part" of an API.

I'm probably late, but I want to add that there is the AdrotecWebApiBundle for the breeze.server.php library which is a server counterpart to the Breeze.js library. Among other features breeze provides powerful data query capabilities:

Query in a JavaScript query language with filters, ordering, and paging. Breeze queries implement the Open Data Protocol (OData) query standard so you can “expand” the result with related entities or “project” over the data to cherry pick columns and flatten object graphs. Web API, OData, and many other service providers can implement the OData query spec.

So if one decides to go with OData queries it may be worth looking.

Im evaluating the same problem. At the present time I consider few options:

An implementation example is shown below:

public function getFilters() {
    $filters = $this->query->get('filter', '');
    if (!empty($filters)) {
        try {
            $fp = new FilterParser();
            $filters = $fp->parse($filters);
        } catch (SyntaxErrorException $e) {
            throw new BadRequestException('Invalid filter definition. '.$e->getMessage(), null, $e);
        }
    } else {
        return null;
    }
    return $filters;
}

Usage extracted from https://github.com/Eyjafjallajokull/symfony-rest-bundle/blob/master/QueryParams/QueryParams.php

  • The most complete solution: If you want to implement a full odata compliant API now is available the official odata provider libraries built for PHP (take a look to IDataServiceQueryProvider ). https://github.com/MSOpenTech/odataphpprod By the moment good examples of implementations using these libraries are needed.