Vox icon indicating copy to clipboard operation
Vox copied to clipboard

New resource as relation fails to create

Open Thiryn opened this issue 7 years ago • 3 comments

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)
        }
    }

Thiryn avatar Apr 17 '18 08:04 Thiryn

@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.

aronbalog avatar Apr 18 '18 18:04 aronbalog

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.

Thiryn avatar Apr 19 '18 07:04 Thiryn

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

aronbalog avatar Apr 20 '18 22:04 aronbalog