remove mapstructure from blockstorage,cdn,compute,db pkgs
diff --git a/openstack/db/v1/configurations/results.go b/openstack/db/v1/configurations/results.go
index 5128b01..a708abd 100644
--- a/openstack/db/v1/configurations/results.go
+++ b/openstack/db/v1/configurations/results.go
@@ -1,22 +1,19 @@
 package configurations
 
 import (
-	"fmt"
-	"reflect"
 	"time"
 
-	"github.com/mitchellh/mapstructure"
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
 
 // Config represents a configuration group API resource.
 type Config struct {
-	Created              time.Time `mapstructure:"-"`
-	Updated              time.Time `mapstructure:"-"`
-	DatastoreName        string    `mapstructure:"datastore_name"`
-	DatastoreVersionID   string    `mapstructure:"datastore_version_id"`
-	DatastoreVersionName string    `mapstructure:"datastore_version_name"`
+	Created              time.Time `json:"created"`
+	Updated              time.Time `json:"updated"`
+	DatastoreName        string    `json:"datastore_name"`
+	DatastoreVersionID   string    `json:"datastore_version_id"`
+	DatastoreVersionName string    `json:"datastore_version_name"`
 	Description          string
 	ID                   string
 	Name                 string
@@ -31,55 +28,17 @@
 // IsEmpty indicates whether a ConfigPage is empty.
 func (r ConfigPage) IsEmpty() (bool, error) {
 	is, err := ExtractConfigs(r)
-	if err != nil {
-		return true, err
-	}
-	return len(is) == 0, nil
+	return len(is) == 0, err
 }
 
 // ExtractConfigs will retrieve a slice of Config structs from a page.
 func ExtractConfigs(page pagination.Page) ([]Config, error) {
-	casted := page.(ConfigPage).Body
-
-	var resp struct {
-		Configs []Config `mapstructure:"configurations" json:"configurations"`
+	r := page.(ConfigPage)
+	var s struct {
+		Configs []Config `json:"configurations"`
 	}
-
-	if err := mapstructure.Decode(casted, &resp); err != nil {
-		return nil, err
-	}
-
-	var vals []interface{}
-	switch casted.(type) {
-	case map[string]interface{}:
-		vals = casted.(map[string]interface{})["configurations"].([]interface{})
-	case map[string][]interface{}:
-		vals = casted.(map[string][]interface{})["configurations"]
-	default:
-		return resp.Configs, fmt.Errorf("Unknown type: %v", reflect.TypeOf(casted))
-	}
-
-	for i, v := range vals {
-		val := v.(map[string]interface{})
-
-		if t, ok := val["created"].(string); ok && t != "" {
-			creationTime, err := time.Parse(time.RFC3339, t)
-			if err != nil {
-				return resp.Configs, err
-			}
-			resp.Configs[i].Created = creationTime
-		}
-
-		if t, ok := val["updated"].(string); ok && t != "" {
-			updatedTime, err := time.Parse(time.RFC3339, t)
-			if err != nil {
-				return resp.Configs, err
-			}
-			resp.Configs[i].Updated = updatedTime
-		}
-	}
-
-	return resp.Configs, nil
+	err := r.ExtractInto(&s)
+	return s.Configs, err
 }
 
 type commonResult struct {
@@ -88,34 +47,11 @@
 
 // Extract will retrieve a Config resource from an operation result.
 func (r commonResult) Extract() (*Config, error) {
-	if r.Err != nil {
-		return nil, r.Err
+	var s struct {
+		Config *Config `json:"configuration"`
 	}
-
-	var response struct {
-		Config Config `mapstructure:"configuration"`
-	}
-
-	err := mapstructure.Decode(r.Body, &response)
-	val := r.Body.(map[string]interface{})["configuration"].(map[string]interface{})
-
-	if t, ok := val["created"].(string); ok && t != "" {
-		creationTime, err := time.Parse(time.RFC3339, t)
-		if err != nil {
-			return &response.Config, err
-		}
-		response.Config.Created = creationTime
-	}
-
-	if t, ok := val["updated"].(string); ok && t != "" {
-		updatedTime, err := time.Parse(time.RFC3339, t)
-		if err != nil {
-			return &response.Config, err
-		}
-		response.Config.Updated = updatedTime
-	}
-
-	return &response.Config, err
+	err := r.ExtractInto(&s)
+	return s.Config, err
 }
 
 // GetResult represents the result of a Get operation.
@@ -145,10 +81,10 @@
 
 // Param represents a configuration parameter API resource.
 type Param struct {
-	Max             int
-	Min             int
+	Max             float64
+	Min             float64
 	Name            string
-	RestartRequired bool `mapstructure:"restart_required" json:"restart_required"`
+	RestartRequired bool `json:"restart_required"`
 	Type            string
 }
 
@@ -160,22 +96,17 @@
 // IsEmpty indicates whether a ParamPage is empty.
 func (r ParamPage) IsEmpty() (bool, error) {
 	is, err := ExtractParams(r)
-	if err != nil {
-		return true, err
-	}
-	return len(is) == 0, nil
+	return len(is) == 0, err
 }
 
 // ExtractParams will retrieve a slice of Param structs from a page.
 func ExtractParams(page pagination.Page) ([]Param, error) {
-	casted := page.(ParamPage).Body
-
-	var resp struct {
-		Params []Param `mapstructure:"configuration-parameters" json:"configuration-parameters"`
+	r := page.(ParamPage)
+	var s struct {
+		Params []Param `json:"configuration-parameters"`
 	}
-
-	err := mapstructure.Decode(casted, &resp)
-	return resp.Params, err
+	err := r.ExtractInto(&s)
+	return s.Params, err
 }
 
 // ParamResult represents the result of an operation which retrieves details
@@ -186,12 +117,7 @@
 
 // Extract will retrieve a param from an operation result.
 func (r ParamResult) Extract() (*Param, error) {
-	if r.Err != nil {
-		return nil, r.Err
-	}
-
-	var param Param
-
-	err := mapstructure.Decode(r.Body, &param)
-	return &param, err
+	var s Param
+	err := r.ExtractInto(&s)
+	return &s, err
 }
diff --git a/openstack/db/v1/databases/results.go b/openstack/db/v1/databases/results.go
index 9126329..0479d0e 100644
--- a/openstack/db/v1/databases/results.go
+++ b/openstack/db/v1/databases/results.go
@@ -1,7 +1,6 @@
 package databases
 
 import (
-	"github.com/mitchellh/mapstructure"
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
@@ -37,36 +36,28 @@
 // IsEmpty checks to see whether the collection is empty.
 func (page DBPage) IsEmpty() (bool, error) {
 	dbs, err := ExtractDBs(page)
-	if err != nil {
-		return true, err
-	}
-	return len(dbs) == 0, nil
+	return len(dbs) == 0, err
 }
 
 // NextPageURL will retrieve the next page URL.
 func (page DBPage) NextPageURL() (string, error) {
-	type resp struct {
-		Links []gophercloud.Link `mapstructure:"databases_links"`
+	var s struct {
+		Links []gophercloud.Link `json:"databases_links"`
 	}
-
-	var r resp
-	err := mapstructure.Decode(page.Body, &r)
+	err := page.ExtractInto(&s)
 	if err != nil {
 		return "", err
 	}
-
-	return gophercloud.ExtractNextURL(r.Links)
+	return gophercloud.ExtractNextURL(s.Links)
 }
 
 // ExtractDBs will convert a generic pagination struct into a more
 // relevant slice of DB structs.
 func ExtractDBs(page pagination.Page) ([]Database, error) {
-	casted := page.(DBPage).Body
-
-	var response struct {
-		Databases []Database `mapstructure:"databases"`
+	r := page.(DBPage)
+	var s struct {
+		Databases []Database `json:"databases"`
 	}
-
-	err := mapstructure.Decode(casted, &response)
-	return response.Databases, err
+	err := r.ExtractInto(&s)
+	return s.Databases, err
 }
diff --git a/openstack/db/v1/datastores/results.go b/openstack/db/v1/datastores/results.go
index a0b3ee8..e893884 100644
--- a/openstack/db/v1/datastores/results.go
+++ b/openstack/db/v1/datastores/results.go
@@ -1,7 +1,6 @@
 package datastores
 
 import (
-	"github.com/mitchellh/mapstructure"
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
@@ -15,7 +14,7 @@
 
 // Datastore represents a Datastore API resource.
 type Datastore struct {
-	DefaultVersion string `json:"default_version" mapstructure:"default_version"`
+	DefaultVersion string `json:"default_version"`
 	ID             string
 	Links          []gophercloud.Link
 	Name           string
@@ -28,7 +27,7 @@
 type DatastorePartial struct {
 	Version   string
 	Type      string
-	VersionID string `json:"version_id" mapstructure:"version_id"`
+	VersionID string `json:"version_id"`
 }
 
 // GetResult represents the result of a Get operation.
@@ -49,40 +48,30 @@
 // IsEmpty indicates whether a Datastore collection is empty.
 func (r DatastorePage) IsEmpty() (bool, error) {
 	is, err := ExtractDatastores(r)
-	if err != nil {
-		return true, err
-	}
-	return len(is) == 0, nil
+	return len(is) == 0, err
 }
 
 // ExtractDatastores retrieves a slice of datastore structs from a paginated
 // collection.
 func ExtractDatastores(page pagination.Page) ([]Datastore, error) {
-	casted := page.(DatastorePage).Body
-
-	var resp struct {
-		Datastores []Datastore `mapstructure:"datastores" json:"datastores"`
+	r := page.(DatastorePage)
+	var s struct {
+		Datastores []Datastore `json:"datastores"`
 	}
-
-	err := mapstructure.Decode(casted, &resp)
-	return resp.Datastores, err
+	err := r.ExtractInto(&s)
+	return s.Datastores, err
 }
 
 // Extract retrieves a single Datastore struct from an operation result.
 func (r GetResult) Extract() (*Datastore, error) {
-	if r.Err != nil {
-		return nil, r.Err
+	var s struct {
+		Datastore *Datastore `json:"datastore"`
 	}
-
-	var response struct {
-		Datastore Datastore `mapstructure:"datastore"`
-	}
-
-	err := mapstructure.Decode(r.Body, &response)
-	return &response.Datastore, err
+	err := r.ExtractInto(&s)
+	return s.Datastore, err
 }
 
-// DatastorePage represents a page of version resources.
+// VersionPage represents a page of version resources.
 type VersionPage struct {
 	pagination.SinglePageBase
 }
@@ -90,34 +79,24 @@
 // IsEmpty indicates whether a collection of version resources is empty.
 func (r VersionPage) IsEmpty() (bool, error) {
 	is, err := ExtractVersions(r)
-	if err != nil {
-		return true, err
-	}
-	return len(is) == 0, nil
+	return len(is) == 0, err
 }
 
 // ExtractVersions retrieves a slice of versions from a paginated collection.
 func ExtractVersions(page pagination.Page) ([]Version, error) {
-	casted := page.(VersionPage).Body
-
-	var resp struct {
-		Versions []Version `mapstructure:"versions" json:"versions"`
+	r := page.(VersionPage)
+	var s struct {
+		Versions []Version `json:"versions"`
 	}
-
-	err := mapstructure.Decode(casted, &resp)
-	return resp.Versions, err
+	err := r.ExtractInto(&s)
+	return s.Versions, err
 }
 
 // Extract retrieves a single Version struct from an operation result.
 func (r GetVersionResult) Extract() (*Version, error) {
-	if r.Err != nil {
-		return nil, r.Err
+	var s struct {
+		Version *Version `json:"version"`
 	}
-
-	var response struct {
-		Version Version `mapstructure:"version"`
-	}
-
-	err := mapstructure.Decode(r.Body, &response)
-	return &response.Version, err
+	err := r.ExtractInto(&s)
+	return s.Version, err
 }
diff --git a/openstack/db/v1/flavors/requests_test.go b/openstack/db/v1/flavors/requests_test.go
index 387b076..ce01759 100644
--- a/openstack/db/v1/flavors/requests_test.go
+++ b/openstack/db/v1/flavors/requests_test.go
@@ -25,7 +25,7 @@
 
 		expected := []Flavor{
 			Flavor{
-				ID:   "1",
+				ID:   1,
 				Name: "m1.tiny",
 				RAM:  512,
 				Links: []gophercloud.Link{
@@ -34,7 +34,7 @@
 				},
 			},
 			Flavor{
-				ID:   "2",
+				ID:   2,
 				Name: "m1.small",
 				RAM:  1024,
 				Links: []gophercloud.Link{
@@ -43,7 +43,7 @@
 				},
 			},
 			Flavor{
-				ID:   "3",
+				ID:   3,
 				Name: "m1.medium",
 				RAM:  2048,
 				Links: []gophercloud.Link{
@@ -52,7 +52,7 @@
 				},
 			},
 			Flavor{
-				ID:   "4",
+				ID:   4,
 				Name: "m1.large",
 				RAM:  4096,
 				Links: []gophercloud.Link{
@@ -79,7 +79,7 @@
 	th.AssertNoErr(t, err)
 
 	expected := &Flavor{
-		ID:   "1",
+		ID:   1,
 		Name: "m1.tiny",
 		RAM:  512,
 		Links: []gophercloud.Link{
diff --git a/openstack/db/v1/flavors/results.go b/openstack/db/v1/flavors/results.go
index 508f5a4..d2a5cba 100644
--- a/openstack/db/v1/flavors/results.go
+++ b/openstack/db/v1/flavors/results.go
@@ -1,7 +1,6 @@
 package flavors
 
 import (
-	"github.com/mitchellh/mapstructure"
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/pagination"
 )
@@ -12,34 +11,24 @@
 }
 
 // Extract provides access to the individual Flavor returned by the Get function.
-func (gr GetResult) Extract() (*Flavor, error) {
-	if gr.Err != nil {
-		return nil, gr.Err
+func (r GetResult) Extract() (*Flavor, error) {
+	var s struct {
+		Flavor *Flavor `json:"flavor"`
 	}
-
-	var result struct {
-		Flavor Flavor `mapstructure:"flavor"`
-	}
-
-	decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
-		WeaklyTypedInput: true,
-		Result:           &result,
-	})
-
-	err = decoder.Decode(gr.Body)
-	return &result.Flavor, err
+	err := r.ExtractInto(&s)
+	return s.Flavor, err
 }
 
 // Flavor records represent (virtual) hardware configurations for server resources in a region.
 type Flavor struct {
 	// The flavor's unique identifier.
-	ID string `mapstructure:"id"`
+	ID int `json:"id"`
 
 	// The RAM capacity for the flavor.
-	RAM int `mapstructure:"ram"`
+	RAM int `json:"ram"`
 
 	// The Name field provides a human-readable moniker for the flavor.
-	Name string `mapstructure:"name"`
+	Name string `json:"name"`
 
 	// Links to access the flavor.
 	Links []gophercloud.Link
@@ -51,42 +40,29 @@
 }
 
 // IsEmpty determines if a page contains any results.
-func (p FlavorPage) IsEmpty() (bool, error) {
-	flavors, err := ExtractFlavors(p)
-	if err != nil {
-		return true, err
-	}
-	return len(flavors) == 0, nil
+func (page FlavorPage) IsEmpty() (bool, error) {
+	flavors, err := ExtractFlavors(page)
+	return len(flavors) == 0, err
 }
 
 // NextPageURL uses the response's embedded link reference to navigate to the next page of results.
-func (p FlavorPage) NextPageURL() (string, error) {
-	type resp struct {
-		Links []gophercloud.Link `mapstructure:"flavors_links"`
+func (page FlavorPage) NextPageURL() (string, error) {
+	var s struct {
+		Links []gophercloud.Link `json:"flavors_links"`
 	}
-
-	var r resp
-	err := mapstructure.Decode(p.Body, &r)
+	err := page.ExtractInto(&s)
 	if err != nil {
 		return "", err
 	}
-
-	return gophercloud.ExtractNextURL(r.Links)
+	return gophercloud.ExtractNextURL(s.Links)
 }
 
 // ExtractFlavors provides access to the list of flavors in a page acquired from the List operation.
 func ExtractFlavors(page pagination.Page) ([]Flavor, error) {
-	casted := page.(FlavorPage).Body
-	var container struct {
-		Flavors []Flavor `mapstructure:"flavors"`
+	r := page.(FlavorPage)
+	var s struct {
+		Flavors []Flavor `json:"flavors"`
 	}
-
-	decoder, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
-		WeaklyTypedInput: true,
-		Result:           &container,
-	})
-
-	err = decoder.Decode(casted)
-
-	return container.Flavors, err
+	err := r.ExtractInto(&s)
+	return s.Flavors, err
 }
diff --git a/openstack/db/v1/instances/fixtures.go b/openstack/db/v1/instances/fixtures.go
index d30d889..d0a3856 100644
--- a/openstack/db/v1/instances/fixtures.go
+++ b/openstack/db/v1/instances/fixtures.go
@@ -24,7 +24,7 @@
     "version": "5.6"
   },
   "flavor": {
-    "id": "1",
+    "id": 1,
     "links": [
       {
         "href": "https://my-openstack.com/v1.0/1234/flavors/1",
@@ -112,7 +112,7 @@
 	Created: timeVal,
 	Updated: timeVal,
 	Flavor: flavors.Flavor{
-		ID: "1",
+		ID: 1,
 		Links: []gophercloud.Link{
 			gophercloud.Link{Href: "https://my-openstack.com/v1.0/1234/flavors/1", Rel: "self"},
 			gophercloud.Link{Href: "https://my-openstack.com/v1.0/1234/flavors/1", Rel: "bookmark"},
diff --git a/openstack/db/v1/instances/results.go b/openstack/db/v1/instances/results.go
index 46731ef..905b32c 100644
--- a/openstack/db/v1/instances/results.go
+++ b/openstack/db/v1/instances/results.go
@@ -1,11 +1,8 @@
 package instances
 
 import (
-	"fmt"
-	"reflect"
 	"time"
 
-	"github.com/mitchellh/mapstructure"
 	"github.com/gophercloud/gophercloud"
 	"github.com/gophercloud/gophercloud/openstack/db/v1/datastores"
 	"github.com/gophercloud/gophercloud/openstack/db/v1/flavors"
@@ -24,10 +21,10 @@
 // Instance represents a remote MySQL instance.
 type Instance struct {
 	// Indicates the datetime that the instance was created
-	Created time.Time `mapstructure:"-"`
+	Created time.Time `json:"created"`
 
 	// Indicates the most recent datetime that the instance was updated.
-	Updated time.Time `mapstructure:"-"`
+	Updated time.Time `json:"updated"`
 
 	// Indicates the hardware flavor the instance uses.
 	Flavor flavors.Flavor
@@ -80,34 +77,11 @@
 
 // Extract will extract an Instance from various result structs.
 func (r commonResult) Extract() (*Instance, error) {
-	if r.Err != nil {
-		return nil, r.Err
+	var s struct {
+		Instance *Instance `json:"instance"`
 	}
-
-	var response struct {
-		Instance Instance `mapstructure:"instance"`
-	}
-
-	err := mapstructure.Decode(r.Body, &response)
-	val := r.Body.(map[string]interface{})["instance"].(map[string]interface{})
-
-	if t, ok := val["created"].(string); ok && t != "" {
-		creationTime, err := time.Parse(time.RFC3339, t)
-		if err != nil {
-			return &response.Instance, err
-		}
-		response.Instance.Created = creationTime
-	}
-
-	if t, ok := val["updated"].(string); ok && t != "" {
-		updatedTime, err := time.Parse(time.RFC3339, t)
-		if err != nil {
-			return &response.Instance, err
-		}
-		response.Instance.Updated = updatedTime
-	}
-
-	return &response.Instance, err
+	err := r.ExtractInto(&s)
+	return s.Instance, err
 }
 
 // InstancePage represents a single page of a paginated instance collection.
@@ -118,71 +92,30 @@
 // IsEmpty checks to see whether the collection is empty.
 func (page InstancePage) IsEmpty() (bool, error) {
 	instances, err := ExtractInstances(page)
-	if err != nil {
-		return true, err
-	}
-	return len(instances) == 0, nil
+	return len(instances) == 0, err
 }
 
 // NextPageURL will retrieve the next page URL.
 func (page InstancePage) NextPageURL() (string, error) {
-	type resp struct {
-		Links []gophercloud.Link `mapstructure:"instances_links"`
+	var s struct {
+		Links []gophercloud.Link `json:"instances_links"`
 	}
-
-	var r resp
-	err := mapstructure.Decode(page.Body, &r)
+	err := page.ExtractInto(&s)
 	if err != nil {
 		return "", err
 	}
-
-	return gophercloud.ExtractNextURL(r.Links)
+	return gophercloud.ExtractNextURL(s.Links)
 }
 
 // ExtractInstances will convert a generic pagination struct into a more
 // relevant slice of Instance structs.
 func ExtractInstances(page pagination.Page) ([]Instance, error) {
-	casted := page.(InstancePage).Body
-
-	var resp struct {
-		Instances []Instance `mapstructure:"instances"`
+	r := page.(InstancePage)
+	var s struct {
+		Instances []Instance `json:"instances"`
 	}
-
-	if err := mapstructure.Decode(casted, &resp); err != nil {
-		return nil, err
-	}
-
-	var vals []interface{}
-	switch casted.(type) {
-	case map[string]interface{}:
-		vals = casted.(map[string]interface{})["instances"].([]interface{})
-	case map[string][]interface{}:
-		vals = casted.(map[string][]interface{})["instances"]
-	default:
-		return resp.Instances, fmt.Errorf("Unknown type: %v", reflect.TypeOf(casted))
-	}
-
-	for i, v := range vals {
-		val := v.(map[string]interface{})
-
-		if t, ok := val["created"].(string); ok && t != "" {
-			creationTime, err := time.Parse(time.RFC3339, t)
-			if err != nil {
-				return resp.Instances, err
-			}
-			resp.Instances[i].Created = creationTime
-		}
-
-		if t, ok := val["updated"].(string); ok && t != "" {
-			updatedTime, err := time.Parse(time.RFC3339, t)
-			if err != nil {
-				return resp.Instances, err
-			}
-			resp.Instances[i].Updated = updatedTime
-		}
-	}
-
-	return resp.Instances, nil
+	err := r.ExtractInto(&s)
+	return s.Instances, err
 }
 
 // UserRootResult represents the result of an operation to enable the root user.
@@ -192,17 +125,11 @@
 
 // Extract will extract root user information from a UserRootResult.
 func (r UserRootResult) Extract() (*users.User, error) {
-	if r.Err != nil {
-		return nil, r.Err
+	var s struct {
+		User *users.User `json:"user"`
 	}
-
-	var response struct {
-		User users.User `mapstructure:"user"`
-	}
-
-	err := mapstructure.Decode(r.Body, &response)
-
-	return &response.User, err
+	err := r.ExtractInto(&s)
+	return s.User, err
 }
 
 // ActionResult represents the result of action requests, such as: restarting
diff --git a/openstack/db/v1/users/results.go b/openstack/db/v1/users/results.go
index a2d1508..018b7c3 100644
--- a/openstack/db/v1/users/results.go
+++ b/openstack/db/v1/users/results.go
@@ -1,7 +1,6 @@
 package users
 
 import (
-	"github.com/mitchellh/mapstructure"
 	"github.com/gophercloud/gophercloud"
 	db "github.com/gophercloud/gophercloud/openstack/db/v1/databases"
 	"github.com/gophercloud/gophercloud/pagination"
@@ -37,37 +36,28 @@
 // IsEmpty checks to see whether the collection is empty.
 func (page UserPage) IsEmpty() (bool, error) {
 	users, err := ExtractUsers(page)
-	if err != nil {
-		return true, err
-	}
-	return len(users) == 0, nil
+	return len(users) == 0, err
 }
 
 // NextPageURL will retrieve the next page URL.
 func (page UserPage) NextPageURL() (string, error) {
-	type resp struct {
-		Links []gophercloud.Link `mapstructure:"users_links"`
+	var s struct {
+		Links []gophercloud.Link `json:"users_links"`
 	}
-
-	var r resp
-	err := mapstructure.Decode(page.Body, &r)
+	err := page.ExtractInto(&s)
 	if err != nil {
 		return "", err
 	}
-
-	return gophercloud.ExtractNextURL(r.Links)
+	return gophercloud.ExtractNextURL(s.Links)
 }
 
 // ExtractUsers will convert a generic pagination struct into a more
 // relevant slice of User structs.
 func ExtractUsers(page pagination.Page) ([]User, error) {
-	casted := page.(UserPage).Body
-
-	var response struct {
-		Users []User `mapstructure:"users"`
+	r := page.(UserPage)
+	var s struct {
+		Users []User `json:"users"`
 	}
-
-	err := mapstructure.Decode(casted, &response)
-
-	return response.Users, err
+	err := r.ExtractInto(&s)
+	return s.Users, err
 }