Image or File Uploads in Adonis.js with Cloudinary
Tags: image, adonisjs, cloudinary
Published: 2019-08-06 13:53:45

---
title: Image or File Uploads in Adonis.js with Cloudinary
published: true
description: Image or File Uploads in Adonis.js with Cloudinary
tags: image, adonisjs, cloudinary
---

I just started working with adonis JS a little over 2 months now. I recently have to use Cloudinary in my project and i searched for the best way to loosely use it so as to maintain the readable, expressive and approachable structure of Adonis.

This tutorial assumes you are already familiar with Adonis and Cloudinary. I will explain my approach in steps below. So let's get Started!


##Step 1: Create a new AdonisJS project

Run 

```bash
adonis new cloudinary-integration
``` 
to create a new adonis project. You should get a fresh adonis project (as at the writing of this post, i'm using version *4.1*)

##Step 2: Setup an upload controller

Create a new HTTP controller by running 
```bash
adonis make:controller Upload --type http
``` 
and setup a simple index method as shown below

```js

'use strict'

class UploadController {

	async index ({ request, response }) {

        return response.json({status: true, data: 'It Works '})
    }
}

module.exports = UploadController

```

And of cause update the `/start/routes.js` by adding a new route

```js
'use strict'

const Route = use('Route')

Route.on('/').render('welcome')

//Add this Route
Route.get('/upload', 'UploadController.index')
```

## Step 3: Implementing Cloudinary

At this point, if you do not have a cloudinary account, head over to https://cloudinary.com to create a free account. We would need three major environment variables from cloudinary.

- CLOUDINARY_CLOUD_NAME
- CLOUDINARY_API_KEY
- CLOUDINARY_API_SECRET

Update your `.env` file to have these three `environment variables`. See Screenshot below on where to get them from your cloudinary console.

![](https://thepracticaldev.s3.amazonaws.com/i/jnoeuznjy43dfw8m6cxy.jpg)

So your .env file will now look somewhat like this

```env
HOST=127.0.0.1
PORT=3333
NODE_ENV=development
APP_URL=http://${HOST}:${PORT}
CACHE_VIEWS=false
APP_KEY=iBRP92LhBPRKh0rTIcIo2OuyQNbWCY6C
DB_CONNECTION=sqlite
DB_HOST=127.0.0.1
DB_PORT=3306
DB_USER=root
DB_PASSWORD=
DB_DATABASE=adonis
SESSION_DRIVER=cookie
HASH_DRIVER=bcrypt

#Cloudinary Credentials
CLOUDINARY_CLOUD_NAME=your_cloudinary_cloud_name
CLOUDINARY_API_KEY=your_cloudinary_api_key
CLOUDINARY_API_SECRET=your_cloudinary_api_secret
```

Next, Let's pull in the cloudinary JS SDK from npm (or yarn).

```bash
npm i cloudinary --save
```

Then, create a file `/app/Services/Cloudinary.js` with the following code snippet.

```js
'use strict'

const cloudinary = use('cloudinary')
const Env = use('Env')

cloudinary.config({

	cloud_name: Env.get('CLOUDINARY_CLOUD_NAME'),
	api_key: Env.get('CLOUDINARY_API_KEY'),
	api_secret: Env.get('CLOUDINARY_API_SECRET'),
})

module.exports = {

	upload: async (file) => {

		return new Promise(async (resolve, reject) => {

			try{

				let response = await cloudinary.uploader.upload(file.tmpPath, { folder: 'test'})

				resolve({status: true, url: response.secure_url })
			 
			}catch(error){

				reject({status: false, url: error.message })
			}
		})
	}
}
```

We are returning a promise from an `async` function called `upload` which we would be passing a `file` object to. 

##Step 4: Using the cloudinary Service

Now that we have our Cloudinary service setup. lets create a method in our `app/Http/Controllers/UploadController.js` to handle uploads.

Our `UploadController.js` will now look like this

```js
'use strict'

//Import Cloudinary
const Cloudinary = use('App/Services/Cloudinary')

class UploadController {

	async index ({ request, response }) {

		return response.json({status: true, data: 'It Works '})
	}

	async upload ({ request, response }) {

    	//TODO: Validate. Input.

    	try{

    		if(request.file('image')){

    			let cloudinary_response = await Cloudinary.upload(request.file('image'))

				return response.json(cloudinary_response)
    		}

    		return response.json({status: false, data: 'Please upload an Image.'})
    		
    	}catch(error){

    		//console.log(error)
    		return response.status(500).json({status: false, error: error.message })
    	}

    }
}

module.exports = UploadController
```

one more thing, lets add a route to our new method. Our routes file will now look like so

```js
'use strict'

const Route = use('Route')

Route.on('/').render('welcome')

//Add this Route
Route.get('/upload', 'UploadController.index')
Route.post('/upload', 'UploadController.upload')
```

## Step 5: Testing from Postman

For the purpose of testing, we do not want to use the CSRF protection for now. So in your `/config/shield.js` Update the `csrf` key as below so has to exclude the `/upload` route

```
csrf: {
    enable: true,
    methods: ['POST', 'PUT', 'DELETE'],
    filterUris: ['/upload'],
    cookieOptions: {
      httpOnly: false,
      sameSite: true,
      path: '/',
      maxAge: 7200
    }
  }
```

Now to test our upload route and be sure our implementation is working as expected. Try uploading a file from postman as shown below

![](https://thepracticaldev.s3.amazonaws.com/i/oqctjuony55mlanhrgl0.jpg)

You should be able to see your newly uploaded file from your cloudinary media library.

![](https://thepracticaldev.s3.amazonaws.com/i/6556g3rllzaknc5zj69y.jpg)

That's all folks!