Mapping Active Record Associations
Our API's return object associated objects. Is it possible for multiple object types to be mapped for one endpoint?
i.e:
{
"jobs": [
{
"state": "pending",
"id": "d4f2eb03-3510-4c17-8c95-f0a5c630899a",
"price_cents": 1100,
"notes": null,
"created_at": "2016-01-06T02:40:53.393Z",
"updated_at": "2016-01-06T02:40:53.513Z",
"conversation_id": null,
"total_duration": 779,
"total_distance": 2919,
"received_by": null,
"signature_url": null,
"delivered_at": null,
"distance_travelled": null,
"time_taken": null,
"customer_id": "80ab6ca2-eb63-4ce7-b427-bf14a6163f23",
"customer_rated": null,
"fetcher_rated": null,
"payment_status": "pending",
"picked_up_at": null,
"promotional_code_used": false,
"pickup_id": "18c8edc7-e03f-4734-a9e5-e4c1da5395ed",
"dropoff_id": "fdff59cc-4f4f-4dfd-bfb0-751fd5a1a75b",
"offer_ids": [
"aafc8cce-64e5-44d6-8eb6-d5ff53aa8041"
],
"item_type_id": "ce25c0bc-045c-4b3a-aaad-c8cc466bc32b",
"credit_card_id": "3ebb282d-dd90-4ccf-9b75-3e22f325a6b6"
}
],
"destinations": [
{
"id": "18c8edc7-e03f-4734-a9e5-e4c1da5395ed",
"job_id": "d4f2eb03-3510-4c17-8c95-f0a5c630899a",
"type": "Pickup",
"created_at": "2016-01-06T02:40:53.396Z",
"updated_at": "2016-01-06T02:40:53.396Z",
"coordinates": {
"lat": -37.81007400153584,
"lon": 144.9639367684722
},
"address": "325 Swanston St, Melbourne",
"suburb_name": "MELBOURNE",
"postcode": "3000",
"contact_id": "e6941a6d-d95f-45ee-971a-00d2724dee65",
"suburb_id": "40c02201-b6d3-493c-99c8-7b52daff010e"
},
],
"suburbs": [
{
"id": "40c02201-b6d3-493c-99c8-7b52daff010e",
"name": "MELBOURNE",
"postcode": "3000",
"display_name": "Melbourne, 3000"
},
]
}
also what is recommendation for mapping relationships?
Currently it's not possible to return multiple objects per response in that way, however, if you were to refactor the response to look like this: (ie nested)
{
"destination": {
"id": "18c8edc7-e03f-4734-a9e5-e4c1da5395ed",
"job": {
"state": "pending",
"id": "d4f2eb03-3510-4c17-8c95-f0a5c630899a",
"price_cents": 1100,
"notes": null,
"created_at": "2016-01-06T02:40:53.393Z",
"updated_at": "2016-01-06T02:40:53.513Z",
"conversation_id": null,
"total_duration": 779,
"total_distance": 2919,
"received_by": null,
"signature_url": null,
"delivered_at": null,
"distance_travelled": null,
"time_taken": null,
"customer_id": "80ab6ca2-eb63-4ce7-b427-bf14a6163f23",
"customer_rated": null,
"fetcher_rated": null,
"payment_status": "pending",
"picked_up_at": null,
"promotional_code_used": false,
"pickup_id": "18c8edc7-e03f-4734-a9e5-e4c1da5395ed",
"dropoff_id": "fdff59cc-4f4f-4dfd-bfb0-751fd5a1a75b",
"offer_ids": [
"aafc8cce-64e5-44d6-8eb6-d5ff53aa8041"
],
"item_type_id": "ce25c0bc-045c-4b3a-aaad-c8cc466bc32b",
"credit_card_id": "3ebb282d-dd90-4ccf-9b75-3e22f325a6b6"
},
"type": "Pickup",
"created_at": "2016-01-06T02:40:53.396Z",
"updated_at": "2016-01-06T02:40:53.396Z",
"coordinates": {
"lat": -37.81007400153584,
"lon": 144.9639367684722
},
"address": "325 Swanston St, Melbourne",
"suburb_name": "MELBOURNE",
"postcode": "3000",
"contact_id": "e6941a6d-d95f-45ee-971a-00d2724dee65",
"suburb": {
"id": "40c02201-b6d3-493c-99c8-7b52daff010e",
"name": "MELBOURNE",
"postcode": "3000",
"display_name": "Melbourne, 3000"
}
}
}
And your model had the relations a-la Realm:
class Destination: Object, ApiModel {
dynamic var job: Job?
dynamic var suburb: Suburb?
// ... boilerplate
static func fromJSONMapping() -> JSONMapping {
return [
"id": ApiIdTransform(),
"job": ModelTransform<Job>(),
"suburb": ModelTransform<Suburb>()
// ... More stuff
]
}
}
It should get picked up by the call:
Api<Destination>.get("destinations/abcde-1234") { response in
if let destination = response.object {
print("Destination: \(destination.id)")
print("Suburb: \(destination.suburb?.name)");
}
}
@erkie We have a couple of cases in which associated objects help to keep JSONs small. For example, consider this case:
{
"cars": [
{
"model": "Ford",
"user": {
"username": "exampleuser",
"email": "[email protected]"
}
},
{
"model": "Chevrolet",
"user": {
"username": "exampleuser",
"email": "[email protected]"
}
},
{
"model": "Renault",
"user": {
"username": "exampleuser",
"email": "[email protected]"
}
}
]
}
That JSON contains three times the same user, because it's shared among cars. Using associated objects, it becomes smaller by just having one occurrence of the user:
{
"cars": [
{
"model": "Ford",
"user_id": "1"
},
{
"model": "Chevrolet",
"user_id": "1"
},
{
"model": "Renault",
"user_id": "1"
}
],
"users": [
{
"id": "1",
"username": "exampleuser",
"email": "[email protected]"
}
]
}
Note that this example is quite basic; if user was a bigger object, or there were other nested objects, it could produce significantly bigger JSONs.
Do you think there's a way to handle that scenario?