What's the appropriate way for File validation?


#1

Hi everyone,

Firstly thank you everyone who contributes Adonis.js.

I’m new to Adonis.js and forum. I was playing with uploading file and felt like not validating files in appropriate way. So I’m open to new way to do this.

Let me show you how I do it first.

Let’s assume we have store method.

1 - Defining rules.

First defining rules.

const rules = {
     username: 'required',
     profile_pic: 'required',
    }

2 - Getting values from request

const username = request.only(['username']);

let inputImage = request.file('profile_pic', {
      types: ['image'],
      size: '5mb'
    });

At this point I realized

request.only(['profile_pic']); is empty object. (I’m using https://insomnia.rest/ client for testing API ) that causes “required profile pic”

So I removed from rules profile_pic

const rules = {
     username: 'required',
    }

Put my own validation.

    if (inputImage == null) {
      return {
        message: 'profile image is required'
      }
    }

3 - Validate

Btw, I don’t forget validate request

    const validation = await validate(request.all(), rules)

    if (validation.fails()) {

      return validation.messages();
    }

Is there a better way to do this?

Thanks in advance.


#2

Have you read the doc on file uploads?


#4

Of course, I read it.

I checked three part of docs.

request, validation and file upload.

Request

In the methods part, I didn’t even see file method.

https://adonisjs.com/docs/4.1/request#_methods

Validation

I didn’t see anything related to file upload.

File upload

I know that request.file method accepts two arguments, a field name and an object of validations to be performed, before moving the file.

I’m not sure , it’s the way to validate file upload with Adonis?

Btw, what make you think that I didn’t read docs?


#5

Correct way to validate the file uploads

Yes, so the file uploads example shows the correct way to validate the files. Which is

const file = request.file('image', {
  size: '2mb'
})

await file.move()

When you call file.move, it will run the validations and you can access the errors as

file.error()

“What make you think, I didn’t read the docs”

I thought you are mostly looking into the request docs, since one of your code samples have this request.only(['profile_pic']).

The files are not part of general request body, accessed as request.all() or request.only() or request.input().

The files are accessed using a different method called request.file.

Why validator doesn’t validate the files?

This is one place, where we can improve the validator and define validations among everything else.

`


#6

Thank you for the help!

I clearly understand

requesting file:

const file = request.file('image', {
  size: '2mb'
})

moving it:

await file.move()

showing error if not moved:

 if (!inputImage.moved()) {
      return inputImage.error()
    }

But my question wasn’t about "Correct way to validate the file uploads"

My question was: What’s the best way to show user file input is required.

As I see, validator doesn’t validate the files which’s not a big deal to check if request.file whether is null

as a result

If we need to check if file is required. It’s okay to check with this way

if(!file) return { message: "file is required"};

To check file mime type or file size, we use if not moved part.

P.S

I showed request.only(['profile_pic']) block to reason why Validator shows me error even if I put file.

I think it’s good idea to put your comment to docs.

The files are not part of general request body, accessed as request.all() or request.only() or request.input() .

The files are accessed using a different method called request.file

Thank you again!


#7

Yeah I agree docs can be more clear on this. Also I don’t know how I missed files from the Validator, since it’s not that complex to validate