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

Data validation in AxiosRequestConfig #4200

Closed
p8nut opened this issue Oct 19, 2021 · 5 comments
Closed

Data validation in AxiosRequestConfig #4200

p8nut opened this issue Oct 19, 2021 · 5 comments

Comments

@p8nut
Copy link

p8nut commented Oct 19, 2021

Is your feature request related to a problem? Please describe.

I'm always frustrated when i need to validate the data types from a response after an axios call.

Describe the solution you'd like

like response status, i'd like to validate response data with a validateData in the AxiosRequestConfig.
Also, in typescript, the validateDate could define automatically the returned type.

Describe alternatives you've considered

Wrap my calls in a parent function to check the data type returned.

Additional context

type User = {
    firstname: string;
    lastname: string;
};

function isUser(o: any): o is User {
    return isObject(o) && isString(o['firstname']) && isString(o['lastname']);
}

// Actual type validation.
async function getUser(id: number) {
    const { data } = axios.get(`/users/${id}`);
    if (!isUser(data)) {
        throw Error('invalid response type');
    }
    return data;
}

// Proposed type validation.
async function getUser(id: number): User {
    return axios.get(`/users/${id}`, { validateData: isUser });
}
@raunakjodhawat
Copy link

Interesting idea, I wonder if you could write a custom wrapper for axios for your project and use a callback that checks if the AxiosResponse passes isUser's validation. if yes, you have the response, if no, you can throw the response as an error.

Otherwise, I can pick this feature, and write it in axios.

Instead of passing the isUser function to axios config. I think it would be nice to have a type object. Something like:

{
    firstname: [{
        type: "string",
       required: true 
    }],
    "lastname": [{
            type: "string",
           required: true 
    }]
}

That way you can just pass in the type, and get rid of all sort of type checking needed.

@p8nut
Copy link
Author

p8nut commented Oct 20, 2021

I really like using a data type guard to define the return type of the request.
And using a type guard function could also allow custom validator to be used, like a schema validator or any custom library.

@karlhorky
Copy link
Contributor

karlhorky commented Jul 14, 2022

Nice proposal! 👍

Wonder if a static-types-only solution would be a potentially less complicated alternative.

Eg. supporting configuration of the TypeScript types of the expected request and response for each request path (and checking the type of the request type) would yield most of the benefits without the downside having to run JS code at runtime.

Also, no need to duplicate the configuration { validateData: isUser } being passed every time that you want to make a call to /users/${id} - it will already be configured.

type PathTypes = [
  {
    method: 'PUT',
    path: `/users/${string}`,
    requestBody: {
      name: string,
    },
    responseBody: {
      name: string,
      favoriteColor: string,
    },
  },
];

const instance = axios.create<PathTypes>({
  baseURL: 'https://example.com/api/',
});

const user = await axios.put(`/users/${id}`, {
  namez: 'new name', // ❌ Type error: Property namez does not exist on type
});

user.favoriteColor // ✅ Type: string
user.favoriteColorrr // ❌ Type error: Property favoriteColorrr does not exist on type

Oh wait, maybe generic parameters already exist on instances? Just reading in this closed PR here: #4603

Edit: oh hm, I guess not - seems like axios.create() still doesn't accept generic parameters:

axios/index.d.ts

Lines 392 to 393 in 64dcec5

export interface AxiosStatic extends AxiosInstance {
create(config?: CreateAxiosDefaults): AxiosInstance;

@jasonsaayman
Copy link
Member

Yeah, it should actually work much better than it currently does. The team is working on a full v2 with much better TS support, I have added this to the backlog so I will try prioritise it.

@p8nut
Copy link
Author

p8nut commented Sep 30, 2022

should i close the issue ?

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

No branches or pull requests

4 participants