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

Calling JsonApi.request() does not work

Open Wizofgoz opened this issue 7 years ago • 12 comments

When making a custom request, at least while making a POST request, there are multiple issues. One is avoidable with some hacking but the other renders the function useless.

When a request goes through the req-post middleware, it makes the following call serialize.resource.call(jsonApi, payload.req.model, payload.req.data). From here, it enters _serialize.js where the issues are based.

  1. Since we are making a custom request, modelName is undefined at this point so making this call this.pluralize(modelName) on line 13 leads to an exception being thrown. This, I was able to avoid by changing the pluralize option on the JsonApi instance just before making the request, and changing it back after.

  2. Since we are making a custom request, there is no model and this.modelFor(modelName) returns an empty model. Because of this, on line 20, when the data for the request is supposed to be added to the serializedAttributes variable nothing is added and no data is added to the POST request. Unfortunately, I was unable to find a work-around for this.

Wizofgoz avatar May 23 '18 19:05 Wizofgoz

I can confirm this. There is a workaround by using runMiddleware directly, but this doesn't seem clean since runMiddleware sounds more like internal API.

jsonApi.runMiddleware({url: '...', method: 'POST', params: {}, data: {...}, model: 'yourmodelname'}).then(...)

So I think jsonApi.request(...) should get an additional argument 'model'.

Josta avatar Jul 12 '18 14:07 Josta

Can you please elaborate on what 'custom request' is? Is it possible that you provide an example for this, or even better - add s test use case in the devour package, that is expected to pass but breaks?

tomers avatar Jul 15 '18 12:07 tomers

Hi @tomers, I faced the same issue today. I think @Josta is referring to the "arbitrary" requests that's documented in the readme.

Below is the code I am trying to run

import JsonApi from 'devour-client';
export const api = new JsonApi({apiUrl: 'http://192.168.1.235:3000/'})

let user = api.define('user', {
  email: '',
  password: '',
  token: ''
}, {
    readOnly: ['token']
})

api.request('/users/signup', 'POST', {}, {data: {type: "users",attributes: {email: email,password: password}}, "meta": {}})

When I run this, I get the following error

devour error [Error: API resource definition for model "undefined" not found. Available models: user]

Let me know if you need more information.

vinay-nadig-0042 avatar Mar 28 '19 16:03 vinay-nadig-0042

I also ran into this exact same issue today. Any updates on this?

BlaiseGratton avatar Jul 26 '19 17:07 BlaiseGratton

This seems like an issue with the deserializer not understanding what model to use. We could add a model parameter to the request function. AFAIK request is intended to be used externally (ie. it's not a "private" function).

Auspicus avatar Jul 26 '19 19:07 Auspicus

When you say externally, do you mean a different API than the one being targeted by the models?

I would say request should take a model name as parameter and be a part of the model ecosystem of devour.

If someone wants to make an external request they can just use axios directly.

@Auspicus are you the only contributor at the moment?

daure avatar Aug 15 '19 13:08 daure

That's a good point about clarifying "external". I think maybe this language in the readme is a bit confusing:

// To make arbitrary requests through the middleware stack
jsonApi.request('https://example.com', 'GET', { a_query_param: 3 }, { some_payload_item: 'blah' })

Both the comment and the code could be interpreted as being able to use any endpoint 🤷‍♂

BlaiseGratton avatar Aug 15 '19 15:08 BlaiseGratton

@daure Myself and @tomers are taking care of this project at the moment. I'm able to merge pull requests and deploy to npm but don't have the throughput to contribute my own code.

Auspicus avatar Aug 23 '19 03:08 Auspicus

I see two ways of solving this.

Either encouraging developers to always use the API methods, eg. find, findAll by making the request function internal only (could use new ES6 Symbols or simply prefix with _ to signify private function, and remove from documentation).

OR

Committing to the function being used externally and adding a parameter to tell the request function what model it is fetching.

FWIW you can access the underlying axios client using jsonApi.axios

Auspicus avatar Aug 23 '19 03:08 Auspicus

Thanks, I think we will just used vanillar axios and transform the data ourselves in the cases where find/findAll/etc. doesn't map well to our endpoint URL structure.

daure avatar Aug 26 '19 02:08 daure

@Auspicus or @daure is there any update on this bug/request? Do you guys anticipate resolving it in the near future. To me this is a fairly common problem. In our company we leverage the JSON api to create standardized structures for communicating between the front end and back end. Sometimes we need to make slight deviations from the JSON api standard for business reasons. One of the things that drew me to this library was the ease of use and lack of opinion about how the data models work after the request has responded. Additionally, I'll echo that when I read:

// To make arbitrary requests through the middleware stack
jsonApi.request('https://example.com', 'GET', { a_query_param: 3 }, { some_payload_item: 'blah' })

I expected to be able to make one-off requests. Not necessarily to another api, but to our own api where we chose to break the JSON api standard (or in the case of legacy code; non JSON api end points).

Let me know if there is anything I can do to help flesh out the exact requirements around this. I believe that this library should be able to make one-off requests for the purpose of flexibility and understanding that not all endpoints in a real life company will be built to JSON api standard.

Thanks again for this robust library. Here to help. Sebastian Kline

sebastianKline avatar Nov 25 '19 15:11 sebastianKline

#208

scottconnerly avatar Feb 28 '20 20:02 scottconnerly