Announcing Common Ninja Storage - A Simple API For Adding Storage Capabilities to E-Commerce Apps
Tags: webdev, ecommerce, node, storage
Published: 2022-06-06 12:18:19

We’ve recently built a [new app](https://apps.shopify.com/common-ninja-info-labels-1) for Shopify and other e-commerce platforms. The app allows merchants to add info labels to a product image. This is a very common use case, as merchants frequently create multiple variations of a product image to highlight some of the product's features.

One of the app’s features is the ability to create an image with the info labels editor we’ve built, and then to save it for future use. To make this possible, we needed to integrate with a storage solution such as [AWS S3](https://aws.amazon.com/s3/), [Google Cloud Storage](https://cloud.google.com/storage), [Azure Blob Storage](https://azure.microsoft.com/en-us/services/storage/blobs/), etc.

For some reason, adding this capability and understanding what the best way to save files on a cloud storage was, as well as coding the feature end-to-end in both client and server sides — wasn't an easy task at all (although this is something I've handled dozens of times).

Our stack includes **React**, **Node** and **AWS S3**. Having said that, here are some of the problems we encountered:

* How to send an image from a ReactJS app to a server?
* How to accept an image file in NodeJS?
* How to save an image to AWS S3?
* How to get the uploaded image URL?
* How to create and manage folders for each user?

These seem like trivial questions, but answering each one of them and understanding how they all **play together** is something that can take a long time.

I believe that the main issue here is that there are multiple ways to upload images from client to server — base64, urls, form-data, blobs. So many terms when the only thing you want, as the app's developer, is to allow your users to upload images and files.

## ❓ What is Common Ninja?

Common Ninja is a platform that allows developers to build & monetize apps for e-commerce platforms very easily. With our single e-commerce API you can build your app once, and integrate it with multiple platforms like Shopify, BigCommerce, Wix, WooCommerce, and more. There's no need to rebuild the app and make it work on every platform individually.

In addition, Common Ninja offers a set of APIs and tools that help developers to boost up the development process, and provide payments and storage solutions.

## 📣 Announcing Common Ninja Storage

Common Ninja's Storage solution is a new and easy way for adding storage capabilities to any e-commerce app.

Our API is simple and you can decide whether you want Common Ninja to manage your storage, or to integrate it with your own AWS S3 bucket.

You can read more about the API in our [docs](https://docs.commoninja.com/apis/storage).

## 💻 Code Example

We'll publish a much more technical article soon, but meanwhile, just to taste how easy it is, here's a quick code example from our [Info Labels app](https://apps.shopify.com/common-ninja-info-labels-1) (developed with React & NodeJS).

```typescript
import React, { useState } from 'react';

function FileUpload() {
	const [selectedFile, setSelectedFile] = useState<string | Blob>('');

	const changeHandler = (event: any) => {
		setSelectedFile(event.target.files[0]);
	};

	const uploadImage = async () => {
		try {
			const body = new FormData();
			body.append('file', selectedFile);
			const req = await fetch('/api/storage/files', {
				method: 'POST',
				body,
			});
			const {
				data: { url },
			} = await req.json();

			console.log('File url: ', url);
		} catch (e) {
			console.error('Could not upload image', e);
		}
	};

	return (
		<div>
			<input type="file" name="file" onChange={changeHandler} />
			<div>
				<button onClick={uploadImage}>Upload</button>
			</div>
		</div>
	);
}
```

Next, in our NodeJS server we use Common Ninja's API to upload the file and return its url:

```typescript
import { Request, Response, Router } from 'express';
import CommonNinja from '@commonninja/node-sdk';

const router: any = Router();
const { COMMONNINJA_APP_ID, COMMONNINJA_APP_SECRET } = process.env;

function getCommonNinjaClient(req: Request) {
	if (!COMMONNINJA_APP_ID || !COMMONNINJA_APP_SECRET) {
		throw new Error('Missing Common Ninja app ID or secret key.');
	}

	return new CommonNinja({
		appId: COMMONNINJA_APP_ID,
		appSecret: COMMONNINJA_APP_SECRET,
		accessToken: req.query.token as string,
		env: CommonNinja.envs.production,
		logs: true,
	});
}

router.post('/api/storage/upload', async (req: Request, res: Response) => {
		const client = getCommonNinjaClient(req);
		const result = await client.storage.uploadFile(req.body.file);
		res.send(result.data);
});
```

And that's it! Zero effort and your users can upload images, videos, documents, and any other file you want your app to support.

## 📚 Learn more

If you're not familiar with Common Ninja or how to build your first app using our API, [here's](https://dev.to/commonninja/kick-off-your-first-shopify-app-with-react-nodejs-and-common-ninja-3821) the previous article we wrote about it.

In addition, you can use the following resources to learn more and get help:

📜 [Common Ninja Docs](https://docs.commoninja.com/)
💬 [Discord Community](https://discord.com/invite/cxqUTbvMNd)