Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Defining models and attributes #6

Open
derek-watson opened this issue May 4, 2016 · 5 comments
Open

Defining models and attributes #6

derek-watson opened this issue May 4, 2016 · 5 comments

Comments

@derek-watson
Copy link
Contributor

derek-watson commented May 4, 2016

// 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?

@Emerson
Copy link
Collaborator

Emerson commented May 9, 2016

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
Copy link
Collaborator

Emerson commented May 9, 2016

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.

@billxinli
Copy link
Collaborator

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?

@Emerson
Copy link
Collaborator

Emerson commented May 9, 2016

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

@vicvinc
Copy link

vicvinc commented Jun 6, 2017

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants