diff --git a/jsonapi.services.yml b/jsonapi.services.yml
index a018154..eee9e62 100644
--- a/jsonapi.services.yml
+++ b/jsonapi.services.yml
@@ -44,3 +44,7 @@ services:
     class: Drupal\jsonapi\Routing\RouteEnhancer
     tags:
       - { name: route_enhancer }
+  jsonapi.params.enhancer:
+    class: Drupal\jsonapi\Routing\JsonApiParamEnhancer
+    tags:
+      - { name: route_enhancer }
diff --git a/src/Resource/EntityResource.php b/src/Resource/EntityResource.php
index e8fbc31..3777305 100644
--- a/src/Resource/EntityResource.php
+++ b/src/Resource/EntityResource.php
@@ -4,15 +4,14 @@ namespace Drupal\jsonapi\Resource;
 
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Entity\Query\QueryInterface;
 use Drupal\jsonapi\Configuration\ResourceConfigInterface;
 use Drupal\jsonapi\EntityCollection;
 use Drupal\jsonapi\RequestCacheabilityDependency;
+use Drupal\jsonapi\Routing\Param\JsonApiParamInterface;
 use Drupal\rest\ResourceResponse;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
-use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
-use Symfony\Component\HttpKernel\Exception\HttpException;
-
 
 /**
  * Class EntityResource.
@@ -71,7 +70,12 @@ class EntityResource implements EntityResourceInterface {
     $query = $storage->getQuery();
     $entity_type = $this->entityTypeManager->getDefinition($entity_type_id);
     $query->condition($entity_type->getKey('bundle'), $this->resourceConfig->getBundleId());
-    // TODO: Add filtering support.
+    $params = $request->attributes->get('_route_params');
+    $params = $params['_json_api_params'];
+    // Apply the filters.
+    if (!empty($params['filter'])) {
+      $this->applyFiltersForList($query, $params['filter']);
+    }
     $results = $query->execute();
     // TODO: Make this method testable by removing the "new".
     $entity_collection = new EntityCollection($storage->loadMultiple($results));
@@ -83,6 +87,30 @@ class EntityResource implements EntityResourceInterface {
   }
 
   /**
+   * Applies the filters to the query.
+   *
+   * @param \Drupal\Core\Entity\Query\QueryInterface $query
+   *   The entity query.
+   * @param \Drupal\jsonapi\Routing\Param\JsonApiParamInterface $filter
+   *   The filter parameter.
+   */
+  protected function applyFiltersForList(QueryInterface $query, JsonApiParamInterface $filter) {
+    foreach ($filter->get() as $field_name => $filter_info) {
+      // Deal with multivalue operators.
+      if ($filter_info['multivalue']) {
+        // Add a single condition using all the values and one operator.
+        $query->condition($field_name, $filter_info['value'], $filter_info['operator'][0]);
+      }
+      else {
+        // For every value in the filter, add a condition to the query.
+        foreach ($filter_info['value'] as $index => $item) {
+          $query->condition($field_name, $item, $filter_info['operator'][$index]);
+        }
+      }
+    }
+  }
+
+  /**
    * Adds cacheability metadata to an entity.
    *
    * @param ResourceResponse $response
diff --git a/src/Routing/JsonApiParamEnhancer.php b/src/Routing/JsonApiParamEnhancer.php
new file mode 100644
index 0000000..0ff454d
--- /dev/null
+++ b/src/Routing/JsonApiParamEnhancer.php
@@ -0,0 +1,46 @@
+<?php
+
+namespace Drupal\jsonapi\Routing;
+use Drupal\Core\Routing\Enhancer\RouteEnhancerInterface;
+use Drupal\jsonapi\Routing\Param\CursorPage;
+use Drupal\jsonapi\Routing\Param\Filter;
+use Drupal\jsonapi\Routing\Param\Sort;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Route;
+
+
+/**
+ * Class JsonApiParamEnhancer.
+ *
+ * @package Drupal\jsonapi\Routing
+ */
+class JsonApiParamEnhancer implements RouteEnhancerInterface {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function applies(Route $route) {
+    // This enhancer applies to the JSON API routes.
+    return $route->getDefault('_controller') == Routes::FRONT_CONTROLLER;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function enhance(array $defaults, Request $request) {
+    $options = [];
+    if ($request->query->has('filter')) {
+      $options['filter'] = new Filter($request->query->get('filter'));
+    }
+    if ($request->query->has('sort')) {
+      $options['sort'] = new Sort($request->query->get('sort'));
+    }
+    if ($request->query->has('page')) {
+      $options['page'] = new CursorPage($request->query->get('page'), 50);
+    }
+    $defaults['_json_api_params'] = $options;
+    return $defaults;
+  }
+
+
+}
diff --git a/src/Routing/Param/CursorPage.php b/src/Routing/Param/CursorPage.php
new file mode 100644
index 0000000..c462e63
--- /dev/null
+++ b/src/Routing/Param/CursorPage.php
@@ -0,0 +1,56 @@
+<?php
+
+namespace Drupal\jsonapi\Routing\Param;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
+
+
+/**
+ * Class Page.
+ *
+ * @package Drupal\jsonapi\Routing\Param
+ */
+class CursorPage extends JsonApiParamBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  const KEY_NAME = 'page';
+
+  /**
+   * Max size.
+   *
+   * @var int
+   */
+  protected $maxSize = 50;
+
+  /**
+   * Instantiates a CursorPage object.
+   *
+   * @param string|\string[] $original
+   *   The original user generated data.
+   * @param int $max_size
+   *   The maximum size for the pager.
+   */
+  public function __construct($original, $max_size = NULL) {
+    parent::__construct($original);
+    if ($max_size) {
+      $this->maxSize = $max_size;
+    }
+  }
+
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function expand() {
+    if (!is_array($this->original)) {
+      throw new BadRequestHttpException('The page parameter needs to be an array.');
+    }
+    $output = $this->original + ['size' => $this->maxSize];
+    $output['size'] = $output['size'] > $this->maxSize ?
+      $this->maxSize :
+      $output['size'];
+    return $output;
+  }
+
+}
diff --git a/src/Routing/Param/Filter.php b/src/Routing/Param/Filter.php
new file mode 100644
index 0000000..49e2678
--- /dev/null
+++ b/src/Routing/Param/Filter.php
@@ -0,0 +1,64 @@
+<?php
+
+namespace Drupal\jsonapi\Routing\Param;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
+
+
+/**
+ * Class Filter.
+ *
+ * @package Drupal\jsonapi\Routing\Param
+ */
+class Filter extends JsonApiParamBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  const KEY_NAME = 'filter';
+
+  protected static $multivalue_operators = ['IN', 'NOT IN', 'BETWEEN'];
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function expand() {
+    // We should always get an array for the filter.
+    if (!is_array($this->original)) {
+      throw new BadRequestHttpException('Incorrect value passed to the filter parameter.');
+    }
+    return array_map(function ($item) {
+      $filter = $item;
+      if (!is_array($filter) || empty($filter['value'])) {
+        // This is the filter[$field_name]=$value scenario.
+        $filter = ['value' => [$filter]];
+      }
+      if (is_string($filter['value'])) {
+        // This is the filter[$field_name][value]=$value scenario.
+        $filter['value'] = [$filter['value']];
+      }
+      if (empty($filter['operator'])) {
+        // Add the default operator for every value.
+        $filter['operator'] = array_map(function () {
+          return '=';
+        }, $filter['value']);
+      }
+      if (is_string($filter['operator'])) {
+        $filter['operator'] = [$filter['operator']];
+      }
+      // If there are more values than operators, check the operator type.
+      if (count($filter['value']) != count($filter['operator'])) {
+        if (in_array($filter['operator'][0], static::$multivalue_operators)) {
+          // If this is a multiple value operator, just use the first operator.
+          $filter['operator'] = [$filter['operator'][0]];
+        }
+        else {
+          // Pad the operators with '='.
+          $filter['operator'] = array_pad($filter['operator'], count($filter['value']), '=');
+        }
+      }
+      $filter['multivalue'] = in_array($filter['operator'][0], static::$multivalue_operators);
+      return $filter;
+    }, $this->original);
+  }
+
+}
diff --git a/src/Routing/Param/JsonApiParamBase.php b/src/Routing/Param/JsonApiParamBase.php
new file mode 100644
index 0000000..3b94bd9
--- /dev/null
+++ b/src/Routing/Param/JsonApiParamBase.php
@@ -0,0 +1,79 @@
+<?php
+
+namespace Drupal\jsonapi\Routing\Param;
+
+
+/**
+ * Class JsonApiParamBase.
+ *
+ * @package Drupal\jsonapi\Routing\Param
+ */
+class JsonApiParamBase implements JsonApiParamInterface {
+
+  /**
+   * The key name.
+   *
+   * @var string
+   */
+  const KEY_NAME = NULL;
+
+  /**
+   * The original data.
+   *
+   * @var string|string[]
+   */
+  protected $original;
+
+  /**
+   * The expanded data.
+   *
+   * @var string|string[]
+   */
+  protected $data;
+
+  /**
+   * Create a parameter object.
+   *
+   * @param string|string[] $original
+   *   The user generated data.
+   */
+  public function __construct($original) {
+    $this->original = $original;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function get() {
+    if (!$this->data) {
+      $this->data = $this->expand();
+    }
+    return $this->data;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getOriginal() {
+    return $this->original;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getKey() {
+    return static::KEY_NAME;
+  }
+
+  /**
+   * Apply all necessary defaults and transformations to the parameter.
+   *
+   * @return string|string[]
+   *   The expanded data.
+   */
+  protected function expand() {
+    // The base implementation does no expansion.
+    return $this->original;
+  }
+
+}
diff --git a/src/Routing/Param/JsonApiParamInterface.php b/src/Routing/Param/JsonApiParamInterface.php
new file mode 100644
index 0000000..a00074d
--- /dev/null
+++ b/src/Routing/Param/JsonApiParamInterface.php
@@ -0,0 +1,37 @@
+<?php
+
+
+namespace Drupal\jsonapi\Routing\Param;
+
+/**
+ * Class JsonApiParamInterface.
+ *
+ * @package Drupal\jsonapi\Routing\Param
+ */
+interface JsonApiParamInterface {
+
+  /**
+   * Gets the original parsed query string param.
+   *
+   * @return string|string[]
+   *   The original value.
+   */
+  public function getOriginal();
+
+  /**
+   * Gets the expanded value with defaults.
+   *
+   * @return string|string[]
+   *   The query string value.
+   */
+  public function get();
+
+  /**
+   * Gets the key of the parameter.
+   *
+   * @return string
+   *   The key.
+   */
+  public function getKey();
+
+}
diff --git a/src/Routing/Param/Sort.php b/src/Routing/Param/Sort.php
new file mode 100644
index 0000000..6e5eecd
--- /dev/null
+++ b/src/Routing/Param/Sort.php
@@ -0,0 +1,39 @@
+<?php
+
+namespace Drupal\jsonapi\Routing\Param;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
+
+
+/**
+ * Class Sort.
+ *
+ * @package Drupal\jsonapi\Routing\Param
+ */
+class Sort extends JsonApiParamBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  const KEY_NAME = 'sort';
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function expand() {
+    if (!is_string($this->original) || empty($this->original)) {
+      throw new BadRequestHttpException('You need to provide a string for the sort parameter.');
+    }
+    return array_map(function ($item) {
+      $sort = $item;
+      // Expand every coma-separated sort value.
+      $sort = ['value' => $sort, 'direction' => 'ASC'];
+      // If the value starts with a minus symbol, then it's descending.
+      if ($sort['value']{0} == '-') {
+        $sort['direction'] = 'DESC';
+        $sort['value'] = substr($sort['value'], 1);
+      }
+      return $sort;
+    }, explode(',', $this->original));
+  }
+
+}
diff --git a/src/Routing/Routes.php b/src/Routing/Routes.php
index 6443ae2..2da0aaa 100644
--- a/src/Routing/Routes.php
+++ b/src/Routing/Routes.php
@@ -15,6 +15,15 @@ use Symfony\Component\Routing\RouteCollection;
 class Routes implements ContainerInjectionInterface {
 
   /**
+   * The front controller for the JSON API routes.
+   *
+   * All routes will use this callback to bootstrap the JSON API process.
+   *
+   * @var string
+   */
+  const FRONT_CONTROLLER = '\Drupal\jsonapi\RequestHandler::handle';
+
+  /**
    * The entity type manager object.
    *
    * @var \Drupal\Core\Entity\EntityTypeManagerInterface
@@ -66,7 +75,7 @@ class Routes implements ContainerInjectionInterface {
       $route_key = sprintf('%s.dynamic.%s.', $prefix, $resource->getTypeName());
       // Add the collection route.
       $defaults = [
-        '_controller' => '\Drupal\jsonapi\RequestHandler::handle',
+        '_controller' => static::FRONT_CONTROLLER,
       ];
 
       // Collection endpoint, like /api/photos.
diff --git a/tests/src/Kernel/Normalizer/DocumentRootNormalizerTest.php b/tests/src/Kernel/Normalizer/DocumentRootNormalizerTest.php
index 4278d68..5067bc1 100644
--- a/tests/src/Kernel/Normalizer/DocumentRootNormalizerTest.php
+++ b/tests/src/Kernel/Normalizer/DocumentRootNormalizerTest.php
@@ -1,6 +1,6 @@
 <?php
 
-namespace Drupal\jsonapi\Test\Kernel\Normalizer;
+namespace Drupal\Tests\jsonapi\Kernel\Normalizer;
 
 use Drupal\jsonapi\Resource\DocumentWrapper;
 use Drupal\KernelTests\KernelTestBase;
diff --git a/tests/src/Unit/Routing/JsonApiParamEnhancerTest.php b/tests/src/Unit/Routing/JsonApiParamEnhancerTest.php
new file mode 100644
index 0000000..f743301
--- /dev/null
+++ b/tests/src/Unit/Routing/JsonApiParamEnhancerTest.php
@@ -0,0 +1,94 @@
+<?php
+
+namespace Drupal\Tests\jsonapi\Unit\Routing;
+
+use Drupal\jsonapi\Routing\JsonApiParamEnhancer;
+use Drupal\jsonapi\Routing\Param\CursorPage;
+use Drupal\jsonapi\Routing\Param\Filter;
+use Drupal\jsonapi\Routing\Param\Sort;
+use Drupal\jsonapi\Routing\Routes;
+use Drupal\Tests\UnitTestCase;
+use Prophecy\Argument;
+use Prophecy\Promise\ReturnPromise;
+use Symfony\Component\HttpFoundation\ParameterBag;
+use Symfony\Component\HttpFoundation\Request;
+use Symfony\Component\Routing\Route;
+
+
+/**
+ * Class JsonApiParamEnhancerTest.
+ *
+ * @package Drupal\jsonapi\Test\Unit
+ *
+ * @coversDefaultClass \Drupal\jsonapi\Routing\JsonApiParamEnhancer
+ * @group jsonapi
+ */
+class JsonApiParamEnhancerTest extends UnitTestCase {
+
+  /**
+   * @covers ::applies
+   */
+  public function testApplies() {
+    $object = new JsonApiParamEnhancer();
+    $route = $this->prophesize(Route::class);
+    $route->getDefault('_controller')->will(new ReturnPromise([Routes::FRONT_CONTROLLER, 'lorem']));
+
+    $this->assertTrue($object->applies($route->reveal()));
+    $this->assertFalse($object->applies($route->reveal()));
+  }
+
+  /**
+   * @covers ::enhance
+   */
+  public function testEnhanceFilter() {
+    $object = new JsonApiParamEnhancer();
+    $request = $this->prophesize(Request::class);
+    $query = $this->prophesize(ParameterBag::class);
+    $query->get('filter')->willReturn(['filed1' => 'lorem']);
+    $query->has(Argument::type('string'))->willReturn(FALSE);
+    $query->has('filter')->willReturn(TRUE);
+    $request->query = $query->reveal();
+
+    $defaults = $object->enhance([], $request->reveal());
+    $this->assertInstanceOf(Filter::class, $defaults['_json_api_params']['filter']);
+    $this->assertTrue(empty($defaults['_json_api_params']['page']));
+    $this->assertTrue(empty($defaults['_json_api_params']['sort']));
+  }
+
+  /**
+   * @covers ::enhance
+   */
+  public function testEnhancePage() {
+    $object = new JsonApiParamEnhancer();
+    $request = $this->prophesize(Request::class);
+    $query = $this->prophesize(ParameterBag::class);
+    $query->get('page')->willReturn(['cursor' => 'lorem']);
+    $query->has(Argument::type('string'))->willReturn(FALSE);
+    $query->has('page')->willReturn(TRUE);
+    $request->query = $query->reveal();
+
+    $defaults = $object->enhance([], $request->reveal());
+    $this->assertInstanceOf(CursorPage::class, $defaults['_json_api_params']['page']);
+    $this->assertTrue(empty($defaults['_json_api_params']['filter']));
+    $this->assertTrue(empty($defaults['_json_api_params']['sort']));
+  }
+
+  /**
+   * @covers ::enhance
+   */
+  public function testEnhanceSort() {
+    $object = new JsonApiParamEnhancer();
+    $request = $this->prophesize(Request::class);
+    $query = $this->prophesize(ParameterBag::class);
+    $query->get('sort')->willReturn('-lorem');
+    $query->has(Argument::type('string'))->willReturn(FALSE);
+    $query->has('sort')->willReturn(TRUE);
+    $request->query = $query->reveal();
+
+    $defaults = $object->enhance([], $request->reveal());
+    $this->assertInstanceOf(Sort::class, $defaults['_json_api_params']['sort']);
+    $this->assertTrue(empty($defaults['_json_api_params']['page']));
+    $this->assertTrue(empty($defaults['_json_api_params']['filter']));
+  }
+
+}
diff --git a/tests/src/Unit/Routing/Param/CursorPageTest.php b/tests/src/Unit/Routing/Param/CursorPageTest.php
new file mode 100644
index 0000000..3cde055
--- /dev/null
+++ b/tests/src/Unit/Routing/Param/CursorPageTest.php
@@ -0,0 +1,50 @@
+<?php
+
+namespace Drupal\Tests\jsonapi\Unit\Routing\Param;
+
+use Drupal\jsonapi\Routing\Param\CursorPage;
+use Drupal\Tests\UnitTestCase;
+
+
+/**
+ * Class CursorPageTest.
+ *
+ * @package Drupal\jsonapi\Test\Unit
+ *
+ * @coversDefaultClass \Drupal\jsonapi\Routing\Param\CursorPage
+ * @group jsonapi
+ */
+class CursorPageTest extends UnitTestCase {
+
+  /**
+   * @covers ::get
+   * @dataProvider getProvider
+   */
+  public function testGet($original, $max_page, $expected) {
+    $pager = new CursorPage($original, $max_page);
+    $this->assertEquals($expected, $pager->get());
+  }
+
+  /**
+   * Data provider for testGet.
+   */
+  public function getProvider() {
+    return [
+      [['cursor' => 12, 'size' => 20], 50, ['cursor' => 12, 'size' => 20]],
+      [['cursor' => 12, 'size' => 60], 50, ['cursor' => 12, 'size' => 50]],
+      [['cursor' => 12], 50, ['cursor' => 12, 'size' => 50]],
+      [['cursor' => 0], 50, ['cursor' => 0, 'size' => 50]],
+      [[], 50, ['size' => 50]],
+    ];
+  }
+
+  /**
+   * @covers ::get
+   * @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
+   */
+  public function testGetFail() {
+    $pager = new CursorPage('lorem');
+    $pager->get();
+  }
+
+}
diff --git a/tests/src/Unit/Routing/Param/FilterTest.php b/tests/src/Unit/Routing/Param/FilterTest.php
new file mode 100644
index 0000000..f668a6d
--- /dev/null
+++ b/tests/src/Unit/Routing/Param/FilterTest.php
@@ -0,0 +1,79 @@
+<?php
+
+namespace Drupal\Tests\jsonapi\Unit\Routing\Param;
+
+use Drupal\jsonapi\Routing\Param\Filter;
+use Drupal\Tests\UnitTestCase;
+
+
+/**
+ * Class FilterTest.
+ *
+ * @package Drupal\jsonapi\Test\Unit
+ *
+ * @coversDefaultClass \Drupal\jsonapi\Routing\Param\Filter
+ * @group jsonapi
+ */
+class FilterTest extends UnitTestCase {
+
+  /**
+   * @covers ::get
+   * @dataProvider getProvider
+   */
+  public function testGet($original, $expected) {
+    $pager = new Filter($original);
+    $this->assertEquals($expected, $pager->get());
+  }
+
+  /**
+   * Data provider for testGet.
+   */
+  public function getProvider() {
+    return [
+      [
+        ['field1' => 'lorem'],
+        ['field1' => ['value' => ['lorem'], 'operator' => ['='], 'multivalue' => FALSE]],
+      ],
+      [
+        [
+          'field1' => 'lorem',
+          'field2' => ['value' => ['lorem'], 'operator' => ['<>'], 'multivalue' => FALSE],
+        ],
+        [
+          'field1' => ['value' => ['lorem'], 'operator' => ['='], 'multivalue' => FALSE],
+          'field2' => ['value' => ['lorem'], 'operator' => ['<>'], 'multivalue' => FALSE],
+        ],
+      ],
+      [
+        ['field1' => ['value' => 'lorem']],
+        ['field1' => ['value' => ['lorem'], 'operator' => ['='], 'multivalue' => FALSE]],
+      ],
+      [
+        ['field1' => ['value' => 'lorem']],
+        ['field1' => ['value' => ['lorem'], 'operator' => ['='], 'multivalue' => FALSE]],
+      ],
+      [
+        ['field1' => ['value' => ['lorem', 'ipsum']]],
+        ['field1' => ['value' => ['lorem', 'ipsum'], 'operator' => ['=', '='], 'multivalue' => FALSE]],
+      ],
+      [
+        ['field1' => ['value' => ['lorem', 'ipsum'], 'operator' => 'IN']],
+        ['field1' => ['value' => ['lorem', 'ipsum'], 'operator' => ['IN'], 'multivalue' => TRUE]],
+      ],
+      [
+        ['field1' => ['value' => ['lorem', 'ipsum'], 'operator' => ['<>']]],
+        ['field1' => ['value' => ['lorem', 'ipsum'], 'operator' => ['<>', '='], 'multivalue' => FALSE]],
+      ],
+    ];
+  }
+
+  /**
+   * @covers ::get
+   * @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
+   */
+  public function testGetFail() {
+    $pager = new Filter('lorem');
+    $pager->get();
+  }
+
+}
diff --git a/tests/src/Unit/Routing/Param/SortTest.php b/tests/src/Unit/Routing/Param/SortTest.php
new file mode 100644
index 0000000..bdd4a5a
--- /dev/null
+++ b/tests/src/Unit/Routing/Param/SortTest.php
@@ -0,0 +1,58 @@
+<?php
+
+namespace Drupal\Tests\jsonapi\Unit\Routing\Param;
+
+use Drupal\jsonapi\Routing\Param\Sort;
+use Drupal\Tests\UnitTestCase;
+
+
+/**
+ * Class SortTest.
+ *
+ * @package Drupal\jsonapi\Test\Unit
+ *
+ * @coversDefaultClass \Drupal\jsonapi\Routing\Param\Sort
+ * @group jsonapi
+ */
+class SortTest extends UnitTestCase {
+
+  /**
+   * @covers ::get
+   * @dataProvider getProvider
+   */
+  public function testGet($original, $expected) {
+    $pager = new Sort($original);
+    $this->assertEquals($expected, $pager->get());
+  }
+
+  /**
+   * Data provider for testGet.
+   */
+  public function getProvider() {
+    return [
+      ['lorem', [['value' => 'lorem', 'direction' => 'ASC']]],
+      ['-lorem', [['value' => 'lorem', 'direction' => 'DESC']]],
+      ['-lorem,ipsum', [['value' => 'lorem', 'direction' => 'DESC'], ['value' => 'ipsum', 'direction' => 'ASC']]],
+      ['-lorem,-ipsum', [['value' => 'lorem', 'direction' => 'DESC'], ['value' => 'ipsum', 'direction' => 'DESC']]],
+    ];
+  }
+
+  /**
+   * @covers ::get
+   * @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
+   */
+  public function testGetFail() {
+    $pager = new Sort(['lorem']);
+    $pager->get();
+  }
+
+  /**
+   * @covers ::get
+   * @expectedException \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
+   */
+  public function testGetEmpty() {
+    $pager = new Sort('');
+    $pager->get();
+  }
+
+}
