diff --git a/restws.entity.inc b/restws.entity.inc
index c147414..b95b3d0 100644
--- a/restws.entity.inc
+++ b/restws.entity.inc
@@ -71,16 +71,16 @@ interface RestWSResourceControllerInterface {
 
   /**
    * Query for a list of resources.
-   * If a format doesn't wants to implement queering, then it should throw an
-   * exception.
+   * If a resource doesn't wants to implement querying, then it should throw an
+   * RestWSException with the 501 HTTP status code.
    *
    * @param array $parameters
    *   A list of parameter to query for, or NULL if all resources should be
    *   returned.
-   * @return
+   * @return array
    *   An array containing the ids of the resources;
    */
-  public function query($parameters);
+  public function query($filters, $meta_controls);
 
   /**
    * Determines access for a given operation and resource.
@@ -168,18 +168,19 @@ class RestWSEntityResourceController implements RestWSResourceControllerInterfac
     entity_delete($this->entityType, $id);
   }
 
-  public function query($parameters) {
+  public function query($filters, $meta_controls) {
     $entity_info = entity_get_info($this->resource());
     $id_key = $entity_info['entity keys']['id'];
+    $limit = variable_get("restws_query_max_limit", 100);
+
     $query =  new EntityFieldQuery();
     $query->entityCondition('entity_type', $this->resource());
+    $query->pager($limit);
     $query_result = $query->execute();
-    $query_result = $query_result[$this->resource()];
+    $query_result = isset($query_result[$this->resource()]) ? $query_result[$this->resource()] : array();
+
+    $result = array_keys($query_result);
 
-    $result = array();
-    foreach ($query_result as $entity_reference) {
-      $result[] = $entity_reference->$id_key;
-    }
     return $result;
   }
 
diff --git a/restws.formats.inc b/restws.formats.inc
index 07d8116..f8c520c 100644
--- a/restws.formats.inc
+++ b/restws.formats.inc
@@ -60,6 +60,8 @@ interface RestWSFormatInterface {
 
   /**
    * Query for a resource.
+   * If a format doesn't wants to implement querying, then it should throw an
+   * RestWSException with the 501 HTTP status code.
    *
    * @param RestWSResourceControllerInterface $resourceController
    *   The controller used to update the resource.
@@ -129,7 +131,7 @@ abstract class RestWSBaseFormat implements RestWSFormatInterface {
   }
 
   public function queryResource($resourceController, $parameters) {
-    $values = $resourceController->query($parameters);
+    $values = $resourceController->query($parameters, NULL);
     foreach ($values as $key => $id) {
       $values[$key] = self::getData($resourceController->wrapper($id));
     }
@@ -245,7 +247,7 @@ class RestWSFormatXML extends RestWSBaseFormat {
     $xml = new DOMDocument('1.0', 'utf-8');
     $element = $xml->createElement($resourceController->resource());
 
-    $values = $resourceController->query($parameters);
+    $values = $resourceController->query($parameters, NULL);
     foreach ($values as $id) {
       $item = $xml->createElement('item');
       self::addToXML($xml, $item, $resourceController->wrapper($id));
@@ -374,6 +376,10 @@ class RestWSFormatRDF extends RestWSBaseFormat {
     throw new RestWSException('Not implemented', 501);
   }
 
+  public function queryResource($resourceController, $parameters) {
+    throw new RestWSException('Not implemented', 501);
+  }
+
   /**
    * Adds the data of the given wrapper to the given XML element.
    */
diff --git a/restws.module b/restws.module
index d383b33..8fd5615 100644
--- a/restws.module
+++ b/restws.module
@@ -122,12 +122,16 @@ function restws_handle_request($op, $format, $resource_name, $id = NULL, $payloa
     if (user_access('access resource ' . $resource_name) && $resource->access($op, $id)) {
       try {
         $method = $op . 'Resource';
-        if ($op == 'create' || $op == 'query') {
+        if ($op == 'create') {
           print $format->$method($resource, $payload);
           drupal_add_http_header('Status', '201 Created');
         }
+        else if ($op == 'query') {
+          print $format->$method($resource, $payload);
+        }
         else {
           print $format->$method($resource, $id, $payload);
+          drupal_add_http_header('Status', '201 Created');
         }
         drupal_add_http_header('Content-Type', $format->mimeType());
       }
@@ -216,40 +220,27 @@ function restws_menu_alter(&$items) {
         );
       }
     }
-    // Resource base path urls with suffix.json and .xml for indexing.
-    if (isset($items[$resource . '.json'])) {
-      // Prepend the page callback and the resource to the page arguments.
-      if (!isset($items[$resource . '.json']['page arguments'])) {
-        $items[$resource . '.json']['page arguments'] = array();
-      }
-      array_unshift($items[$resource . '.json']['page arguments'], $resource, $items[$resource . '.json']['page callback']);
-      $items[$resource . '.json']['page callback'] = 'restws_page_callback';
 
-    }
-    else {
-      $items[$resource . '.json'] = array(
-        'page callback' => 'restws_page_callback',
-        'page arguments' => array($resource),
-        'access callback' => TRUE,
-        'type' => MENU_CALLBACK,
-      );
-    }
-    if (isset($items[$resource . '.xml'])) {
-      // Prepend the page callback and the resource to the page arguments.
-      if (!isset($items[$resource . '.xml']['page arguments'])) {
-        $items[$resource . '.xml']['page arguments'] = array();
-      }
-      array_unshift($item[$resource . '.xml']['page arguments'], $resource, $items[$resource . '.xml']['page callback']);
-      $items[$resource . '.xml']['page callback'] = 'restws_page_callback';
+    foreach (restws_get_format_info() as $format) {
+      $format = drupal_strtolower($format['label']);
+      // Resource base path urls with suffix.json and .xml for indexing.
+      if (isset($items["$resource.$format"])) {
+        // Prepend the page callback and the resource to the page arguments.
+        if (!isset($items["$resource.$format"]['page arguments'])) {
+          $items["$resource.$format"]['page arguments'] = array();
+        }
+        array_unshift($items["$resource.$format"]['page arguments'], $resource, $items["$resource.$format"]['page callback']);
+        $items["$resource.$format"]['page callback'] = 'restws_page_callback';
 
-    }
-    else {
-      $items[$resource . '.xml'] = array(
-        'page callback' => 'restws_page_callback',
-        'page arguments' => array($resource),
-        'access callback' => TRUE,
-        'type' => MENU_CALLBACK,
-      );
+      }
+      else {
+        $items["$resource.$format"] = array(
+          'page callback' => 'restws_page_callback',
+          'page arguments' => array($resource),
+          'access callback' => TRUE,
+          'type' => MENU_CALLBACK,
+        );
+      }
     }
   }
 }
@@ -267,7 +258,7 @@ function restws_page_callback($resource, $page_callback = NULL) {
     $id = substr($id_arg, 0, $pos);
     $format = restws_format($format_name);
   }
-  else if (($pos = strpos($base_uri, '.')) && $format_name = substr($base_uri, $pos + 1)) {
+  elseif (($pos = strpos($base_uri, '.')) && $format_name = substr($base_uri, $pos + 1)) {
     $format = restws_format($format_name);
   }
   else {
@@ -316,8 +307,7 @@ function restws_page_callback($resource, $page_callback = NULL) {
         break;
 
       default:
-        if (!empty($id))
-        {
+        if (!empty($id)) {
           $op = 'view';
         }
         else {
diff --git a/restws.test b/restws.test
index f6dd4bd..c186cb6 100644
--- a/restws.test
+++ b/restws.test
@@ -166,6 +166,30 @@ class RestWSTestCase extends DrupalWebTestCase {
   }
 
   /**
+   * Tests resource querying.
+   */
+  function testQuerying() {
+    $account = $this->drupalCreateUser(array('access content',
+        'bypass node access', 'access resource node')
+    );
+    $this->drupalLogin($account);
+    $nodes = array();
+    for($i=0; $i<5; $i++) {
+      $title = "node$i";
+      $nodes[$i] = $this->drupalCreateNode(array('title' => $title));
+    }
+
+    // Retrieve a list of nodes.
+    $result = $this->httpRequest('node.json', 'GET', $account);
+    $result_nodes = drupal_json_decode($result);
+    foreach ($result_nodes as $key => $node) {
+      $this->assertEqual($nodes[$key]->title, $node['title'], "Node title $key was received correctly.");
+    }
+    $this->assertResponse('200', 'HTTP response code is correct.');
+    $this->assertEqual(curl_getinfo($this->curlHandle, CURLINFO_CONTENT_TYPE), 'application/json', 'HTTP content type is correct.');
+  }
+
+  /**
    * Test that sensitive user data is hidden for the "access user profiles"
    * permission.
    */
