aronbalog / Vox

Swift JSON:API client framework
http://jsonapi.org
MIT License
46 stars 19 forks source link

New resource as relation fails to create #6

Open Thiryn opened 6 years ago

Thiryn commented 6 years ago

The ResourcePool store resources, with a key that use id and type

    private func keyForBasicObject(_ basicObject: [String: String]) -> String {
        return basicObject["id"]! + "_" + basicObject["type"]!
    }  
    private func keyForResource(_ resource: Resource) -> String {
        return resource.id! + "_" + resource.type
    }

So, any Resource without an id can not be stores. Problem is, when you want to create object and relation on client-side, it fails. From the JSONAPI :

Resource Objects “Resource objects” appear in a JSON API document to represent resources.

A resource object MUST contain at least the following top-level members:

id type Exception: The id member is not required when the resource object originates at the client and represents a new resource to be created on the server.


Such a Thing would not work :

import Vox

class Tire: Resource {
    override class var resourceType: String {
        return "tires"
    }
}

class Car: Resource {

    @objc dynamic
    var tires: [Tire]?

    override class var resourceType: String {
        return "cars"
    }
}

func createCar() {
    let c = Car()
    let t = Tire()
    c.tires = [t]
}

I would suggest to add a default id to a resource in ResourcePool::addResource if none is given by the user :

    func addResource(_ resource: Resource) {
        queue.async(flags: .barrier) {
            if resource.id == nil {
                resource.id = resource.internalIdentifier
            }
            self.mapTable.setObject(resource, forKey: self.keyForResource(resource) as NSString)
        }
    }
aronbalog commented 6 years ago

@Thiryn Rule you quoted applies only for resource objects, not the pointer objects inside relationships payload. So I think creating an object and relationship in one request is not supported by JSON:API because you need to set id and type for relationship element. Please correct me if I'm wrong.

Thiryn commented 6 years ago

I think there are drafts about creating nested object here. But even without talking about creating the resource on server-side, for now it is not possible to create resources such as car on client-side with Vox. My use-case is a resource with relations (like car), with a client-side creation of temporary related object (temporary tires) that are not going to be persisted on server-side but used on the application.

aronbalog commented 6 years ago

@Thiryn You are right. I will find a solution and implement it in a couple of days. Stay tuned. Thanks for reporting.