devour-client icon indicating copy to clipboard operation
devour-client copied to clipboard

Defining models and attributes

Open derek-watson opened this issue 8 years ago • 5 comments

// Define Model
jsonApi.define('post', {
  title: '',
  content: '',
  tags: []
})

@Emerson why is this step necessary? I'm unable to find any reference to the models and attributes being used in the codebase. Are there roadmap features that will make use of this? Is it useful on the client?

derek-watson avatar May 04 '16 13:05 derek-watson

This may well be possible and a better approach – but I'd like to think through the logic a little more just to be sure.

The real heavy lifting that this library does is around serializing and deserializing objects according to the JSON API spec. As it stands, the ability to declare a model also gives us:

My main concern is around relationships and flexibility. You can see here exactly what the spec calls for – and it seems like we would have enough information to just do this on the fly.

This response:

{
  "data": [{
    "type": "articles",
    "id": "1",
    "attributes": {
      "title": "JSON API paints my bikeshed!",
      "body": "The shortest article. Ever.",
      "created": "2015-05-22T14:56:29.000Z",
      "updated": "2015-05-22T14:56:28.000Z"
    },
    "relationships": {
      "author": {
        "data": {"id": "42", "type": "people"}
      }
    }
  }],
  "included": [
    {
      "type": "people",
      "id": "42",
      "attributes": {
        "name": "John",
        "age": 80,
        "gender": "male"
      }
    }
  ]
}

Would just be deserialized into:

{
  "id": "1",
  "title": "JSON API paints my bikeshed!",
  "body": "The shortest article. Ever.",
  "created": "2015-05-22T14:56:29.000Z",
  "updated": "2015-05-22T14:56:28.000Z",
  "author": {
    {
      "id": "42",
      "name": "John",
      "age": 80,
      "gender": "male"
    }
  }
}

Emerson avatar May 09 '16 16:05 Emerson

On second thought, I think the main concern is around providing Devour users with an easy way to override some of the internals of the request/response cycle on a per model basis. Without a model definitions, we fallback to "Just add a custom middleware" or find a way to make it work in your own app. In my mind, we (at least) need to provide an easy way to:

  • override serialization for a specific model
  • override deserialization for a specific model

Maybe this is something that we could optionally pass into our calls?

let options = {
  serializer: ()=> {
     /* ... */
  },
  deserializer: ()=> {
     /* ... */
  }
}

devour.one('user', 1).get(params, options)

^ Using this pattern gives us the ease of ad-hoc modeless usage, but also provides users a mechanism to override core functionality and create a sort-of "model" if they need to.

Emerson avatar May 09 '16 16:05 Emerson

Perhaps, we should just make it model optional? If you want to use a model and get the best of the best, great, if you just want to use the library as a URL builder, fine as well?

billxinli avatar May 09 '16 18:05 billxinli

We'd need to rewrite a good deal of the serialization logic – but I'm open to any of it.

Emerson avatar May 09 '16 19:05 Emerson

I think you need this decode library, what I doing to solve this problem is replace the response middleware with a customer middle, like this:

// response handler middleware
const responseMiddleware = {
  name: 'deserialize-response-middleware',
  res: (payload) => {
    console.log('=====json api middleware payload=====', payload)

    let jsonApi = payload.jsonApi
    let status = payload.res.status
    let req = payload.req
    let res = payload.res.data
    let included = res.included
    
    if (status !== 204 && needsDeserialization(req.method)) {
      store.sync(res)
      return store
    }
    // 0 => no need to deserializer
    return 0
  }
}

// request headers
const headers = auth.getAuthHeader()

client.headers = headers
client.replaceMiddleware('response', responseMiddleware)

and then... you can call the serializered collection or resource in the promise :)

hope helps...

vicvinc avatar Jun 06 '17 09:06 vicvinc