openapistack / openapi-client-axios

JavaScript client library for consuming OpenAPI-enabled APIs with axios
https://openapistack.co
MIT License
558 stars 67 forks source link

Schema in query - results in weird URL #49

Open codebykyle opened 3 years ago

codebykyle commented 3 years ago

Hello, I am struggling a bit to get this to work. I am using the following PHP package to make filters: https://github.com/spatie/laravel-query-builder

This expects, by default, to have a filter[filter_name] style URL parameter for searching.

I have the following specs:

Endpoint:

/api/integration-contacts:
    get:
      tags:
        - external
      summary: Gets a list of contacts in the system
      operationId: ListContacts
      description: |
        Searches all contacts in the system
      parameters:
        - in: query
          name: filter
          schema:
            $ref: '#/components/schemas/UserIntegrationSettingsContactsFilter'
      responses:
        '200':
          description: search results matching criteria
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/UserIntegrationSettingsContact'

Filter:

    UserIntegrationSettingsContactsFilter:
      type: object
      properties:
        id:
          type: string
          format: uuid
        user_integration_settings_id:
          type: string
          format: uuid

I have the following action:


        readList({commit}, filter) {
            commit('setIsLoadingList', true);

            return api_server.getClient()
                .then((client) => {
                    client.ListContacts(filter)
                        .then((list) => {
                            commit("setListData", list.data.data)
                        })
                        .catch((error) => {
                            console.log(error);
                        })
                        .finally(() => {
                            commit('setIsLoadingList', false)
                        });
                })
        },

Where the filter parameter is equal to:

{
     filter: {
        user_integration_settings: "someuuid"
     }
}

This produces the following URL: http://api.my-url.local/api/integration-contacts?filter=%5Bobject%20Object%5D

The expected url is: http://api.my-url.local/api/integration-contacts?filter[user_integration_settings_id]=someuuid

Any advice on how to get this to work?

codebykyle commented 3 years ago

I have a solution for this but it may not be ideal.

Following this: https://github.com/axios/axios/issues/738#issuecomment-412905574

I added the following:


api.init().then((client) => {
  client.interceptors.request.use(
      function(config) {
        config.paramsSerializer = (params) => {
          return qs.stringify(params, {
            arrayFormat: "brackets",
            encode: false
          });
        }

        return config;
      },
      function(error) {
        return Promise.reject(error);
      }
  );

  return client;
});

and I was able to get this to work.

npdev453 commented 3 years ago

This expects, by default, to have a filter[filter_name] style URL parameter for searching. Strange expectation of third-party library.

OA3 specs says that by default style for query params is form (see style field desc): https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#parameter-object

form style also should support object: https://github.com/OAI/OpenAPI-Specification/blob/master/versions/3.0.3.md#style-values

But in your example you and your library expected value is style: deepObject and it's not described in parameter style in the example that you provided. (!)

Another problem that openapi-client-axios is currently is not support another values than form for parameter style, but allow you to pass to axiosConfigDefaults an paramsSerializer to handle different cases.

I tried to fix it but couldn't find a graceful way to realize it fast in current library architecture, it passes parameters for serialization on shoulders of 'axios' itself and styles can be mixed for between methods and params also.

So possible better you can change expected params style on your library config.

@anttiviljami, looks like it should be marked as enchantment.