diff --git a/core/modules/rest/src/Plugin/rest/resource/EntityResource.php b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php
index 63857e4..b6c8cb4 100644
--- a/core/modules/rest/src/Plugin/rest/resource/EntityResource.php
+++ b/core/modules/rest/src/Plugin/rest/resource/EntityResource.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\rest\Plugin\rest\resource;
 
+use Drupal\Core\Entity\FieldableEntityInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityStorageException;
 use Drupal\rest\Plugin\ResourceBase;
@@ -49,13 +50,16 @@ public function get(EntityInterface $entity) {
     $response = new ResourceResponse($entity, 200);
     $response->addCacheableDependency($entity);
     $response->addCacheableDependency($entity_access);
-    foreach ($entity as $field_name => $field) {
-      /** @var \Drupal\Core\Field\FieldItemListInterface $field */
-      $field_access = $field->access('view', NULL, TRUE);
-      $response->addCacheableDependency($field_access);
 
-      if (!$field_access->isAllowed()) {
-        $entity->set($field_name, NULL);
+    if ($entity instanceof FieldableEntityInterface) {
+      foreach ($entity as $field_name => $field) {
+        /** @var \Drupal\Core\Field\FieldItemListInterface $field */
+        $field_access = $field->access('view', NULL, TRUE);
+        $response->addCacheableDependency($field_access);
+
+        if (!$field_access->isAllowed()) {
+          $entity->set($field_name, NULL);
+        }
       }
     }
 
@@ -223,6 +227,10 @@ public function delete(EntityInterface $entity) {
    *   If validation errors are found.
    */
   protected function validate(EntityInterface $entity) {
+    // @todo Remove when https://www.drupal.org/node/2164373 is committed.
+    if (!$entity instanceof FieldableEntityInterface) {
+      return;
+    }
     $violations = $entity->validate();
 
     // Remove violations of inaccessible fields as they cannot stem from our
@@ -256,4 +264,32 @@ protected function getBaseRoute($canonical_path, $method) {
     return $route;
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function availableMethods() {
+    $methods = parent::availableMethods();
+    if ($this->isConfigEntityResource()) {
+      // Currently only get is supported for Config Entities.
+      // @todo Remove when supported https://www.drupal.org/node/2300677
+      $unsupported_methods = ['POST', 'PUT', 'DELETE', 'PATCH'];
+      $methods = array_diff($methods, $unsupported_methods);
+    }
+    return $methods;
+  }
+
+  /**
+   * Checks if this resource is for a Config Entity.
+   *
+   * @return bool
+   *   TRUE if the entity is a Config Entity, FALSE otherwise.
+   */
+  protected function isConfigEntityResource() {
+    $entity_type_id = $this->getPluginDefinition()['entity_type'];
+    $entity_type = \Drupal::entityTypeManager()->getDefinition($entity_type_id);
+    $class = $entity_type->getClass();
+    $interfaces = class_implements($class);
+    return in_array('Drupal\Core\Config\Entity\ConfigEntityInterface', $interfaces);
+  }
+
 }
diff --git a/core/modules/rest/src/RequestHandler.php b/core/modules/rest/src/RequestHandler.php
index 2aa3673..5bbb9be 100644
--- a/core/modules/rest/src/RequestHandler.php
+++ b/core/modules/rest/src/RequestHandler.php
@@ -42,6 +42,7 @@ public function handle(RouteMatchInterface $route_match, Request $request) {
       ->createInstance($plugin);
 
     // Deserialize incoming data if available.
+    /** @var \Symfony\Component\Serializer\SerializerInterface $serializer */
     $serializer = $this->container->get('serializer');
     $received = $request->getContent();
     $unserialized = NULL;
diff --git a/core/modules/rest/src/Tests/RESTTestBase.php b/core/modules/rest/src/Tests/RESTTestBase.php
index 092af7c..61f0a51 100644
--- a/core/modules/rest/src/Tests/RESTTestBase.php
+++ b/core/modules/rest/src/Tests/RESTTestBase.php
@@ -217,6 +217,11 @@ protected function entityValues($entity_type) {
             'format' => 'plain_text',
           )),
         );
+      case 'config_test':
+        return [
+          'id' => $this->randomMachineName(),
+          'label' => 'Test label',
+        ];
       case 'node':
         return array('title' => $this->randomString(), 'type' => 'resttest');
       case 'node_type':
@@ -236,7 +241,11 @@ protected function entityValues($entity_type) {
           'entity_id' => 'invalid',
           'field_name' => 'comment',
         ];
-
+      case 'taxonomy_vocabulary':
+        return [
+          'vid' => 'tags',
+          'name' => $this->randomMachineName(),
+        ];
       default:
         return array();
     }
@@ -367,6 +376,12 @@ protected function entityPermissions($entity_type, $operation) {
             return ['administer users'];
 
         }
+      case 'taxonomy_vocabulary':
+        // Currently only view is support by rest for configuration entities.
+        if ($operation === 'view') {
+          // Currently there is no view permissions on configuration entities.
+          return ['administer taxonomy'];
+        }
     }
   }
 
diff --git a/core/modules/rest/src/Tests/ReadTest.php b/core/modules/rest/src/Tests/ReadTest.php
index 31b5db8..6bc66c9 100644
--- a/core/modules/rest/src/Tests/ReadTest.php
+++ b/core/modules/rest/src/Tests/ReadTest.php
@@ -3,6 +3,8 @@
 namespace Drupal\rest\Tests;
 
 use Drupal\Component\Serialization\Json;
+use Drupal\Core\Config\Entity\ConfigEntityInterface;
+use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Url;
 
 /**
@@ -17,7 +19,13 @@ class ReadTest extends RESTTestBase {
    *
    * @var array
    */
-  public static $modules = array('hal', 'rest', 'entity_test');
+  public static $modules = [
+    'hal',
+    'rest',
+    'entity_test',
+    'config_test',
+    'taxonomy',
+  ];
 
   /**
    * Tests several valid and invalid read requests on all entity types.
@@ -25,7 +33,12 @@ class ReadTest extends RESTTestBase {
   public function testRead() {
     // @todo Expand this at least to users.
     // Define the entity types we want to test.
-    $entity_types = array('entity_test', 'node');
+    $entity_types = [
+      'entity_test',
+      'node',
+      'config_test',
+      'taxonomy_vocabulary',
+    ];
     foreach ($entity_types as $entity_type) {
       $this->enableService('entity:' . $entity_type, 'GET');
       // Create a user account that has the required permissions to read
@@ -39,23 +52,39 @@ public function testRead() {
       $entity = $this->entityCreate($entity_type);
       $entity->save();
       // Read it over the REST API.
-      $response = $this->httpRequest($entity->urlInfo()->setRouteParameter('_format', $this->defaultFormat), 'GET');
+      $response = $this->httpRequest($this->getReadUrl($entity), 'GET');
       $this->assertResponse('200', 'HTTP response code is correct.');
       $this->assertHeader('content-type', $this->defaultMimeType);
       $data = Json::decode($response);
       // Only assert one example property here, other properties should be
       // checked in serialization tests.
-      $this->assertEqual($data['uuid'][0]['value'], $entity->uuid(), 'Entity UUID is correct');
+      if ($entity instanceof ConfigEntityInterface) {
+        $this->assertEqual($data['uuid'], $entity->uuid(), 'Entity UUID is correct');
+      }
+      else {
+        $this->assertEqual($data['uuid'][0]['value'], $entity->uuid(), 'Entity UUID is correct');
+      }
 
       // Try to read the entity with an unsupported mime format.
-      $response = $this->httpRequest($entity->urlInfo()->setRouteParameter('_format', 'wrongformat'), 'GET');
+      $this->httpRequest($this->getReadUrl($entity, 'wrongformat'), 'GET');
       $this->assertResponse(406);
       $this->assertHeader('Content-type', 'application/json');
 
       // Try to read an entity that does not exist.
-      $response = $this->httpRequest(Url::fromUri('base://' . $entity_type . '/9999', ['query' => ['_format' => $this->defaultFormat]]), 'GET');
+      $response = $this->httpRequest($this->getReadUrl($entity, $this->defaultFormat, 9999), 'GET');
       $this->assertResponse(404);
-      $path = $entity_type == 'node' ? '/node/{node}' : '/entity_test/{entity_test}';
+      switch ($entity_type) {
+        case 'node':
+          $path = '/node/{node}';
+          break;
+
+        case 'entity_test':
+          $path = '/entity_test/{entity_test}';
+          break;
+
+        default:
+          $path = "/entity/$entity_type/{" . $entity_type . '}';
+      }
       $expected_message = Json::encode(['message' => 'The "' . $entity_type . '" parameter was not converted for the path "' . $path . '" (route name: "rest.entity.' . $entity_type . '.GET.hal_json")']);
       $this->assertIdentical($expected_message, $response, 'Response message is correct.');
 
@@ -65,7 +94,7 @@ public function testRead() {
       if ($entity_type == 'entity_test') {
         $entity->field_test_text->value = 'no access value';
         $entity->save();
-        $response = $this->httpRequest($entity->urlInfo()->setRouteParameter('_format', $this->defaultFormat), 'GET');
+        $response = $this->httpRequest($this->getReadUrl($entity), 'GET');
         $this->assertResponse(200);
         $this->assertHeader('content-type', $this->defaultMimeType);
         $data = Json::decode($response);
@@ -74,14 +103,15 @@ public function testRead() {
 
       // Try to read an entity without proper permissions.
       $this->drupalLogout();
-      $response = $this->httpRequest($entity->urlInfo()->setRouteParameter('_format', $this->defaultFormat), 'GET');
+      $response = $this->httpRequest($this->getReadUrl($entity), 'GET');
       $this->assertResponse(403);
       $this->assertIdentical('{"message":""}', $response);
     }
-    // Try to read a resource which is not REST API enabled.
+    // Try to read a resource, the user entity, which is not REST API enabled.
     $account = $this->drupalCreateUser();
     $this->drupalLogin($account);
-    $response = $this->httpRequest($account->urlInfo()->setRouteParameter('_format', $this->defaultFormat), 'GET');
+    $response = $this->httpRequest($this->getReadUrl($account), 'GET');
+
     // \Drupal\Core\Routing\RequestFormatRouteFilter considers the canonical,
     // non-REST route a match, but a lower quality one: no format restrictions
     // means there's always a match and hence when there is no matching REST
@@ -91,6 +121,7 @@ public function testRead() {
     $this->assertEqual($response, Json::encode([
       'message' => 'Not acceptable format: hal_json',
     ]));
+
   }
 
   /**
@@ -111,8 +142,50 @@ public function testResourceStructure() {
     $entity->save();
 
     // Read it over the REST API.
-    $response = $this->httpRequest($entity->urlInfo()->setRouteParameter('_format', 'json'), 'GET');
+    $this->httpRequest($this->getReadUrl($entity, 'json'), 'GET');
     $this->assertResponse('200', 'HTTP response code is correct.');
   }
 
+  /**
+   * Gets the read URL object for the entity.
+   *
+   * @param \Drupal\Core\Entity\EntityInterface $entity
+   *   The entity to get the url for.
+   * @param string $format
+   *   The format for the URL.
+   * @param string $entity_id
+   *   The entity id to use in the URL.
+   *   Defaults to the entity's id if know given.
+   *
+   * @return \Drupal\Core\Url
+   *   The URL object.
+   */
+  protected function getReadUrl(EntityInterface $entity, $format = NULL, $entity_id = NULL) {
+    if (!$format) {
+      $format = $this->defaultFormat;
+    }
+    if (!$entity_id) {
+      $entity_id = $entity->id();
+    }
+    $entity_type = $entity->getEntityTypeId();
+    if ($entity->hasLinkTemplate('canonical')) {
+      $url = $entity->toUrl('canonical');
+    }
+    else {
+      $route_name = 'rest.entity.' . $entity_type . ".GET.";
+      // If testing unsupported format don't use the format to construct route
+      // name. This would give a route not found exception.
+      if ($format == 'wrongformat') {
+        $route_name .= $this->defaultFormat;
+      }
+      else {
+        $route_name .= $format;
+      }
+      $url = Url::fromRoute($route_name);
+    }
+    $url->setRouteParameter($entity_type, $entity_id);
+    $url->setRouteParameter('_format', $format);
+    return $url;
+  }
+
 }
