お知らせ:

当社は、お客様により充実したサポート情報を迅速に提供するため、本ページのコンテンツは機械翻訳を用いて日本語に翻訳しています。正確かつ最新のサポート情報をご覧いただくには、本内容の英語版を参照してください。

アプリケーションのバックエンドを設定する

このステップでは、アプリケーションに必要なバックエンドロジックを設定します。

コードの追加を開始する前に、必要な依存関係がすべて満たされるように、以下のパッケージをインストールする必要があります。

PhotoStoreApp/serverディレクトリにあるserverフォルダに移動し、以下に示すコマンドを使用して次のパッケージをインストールします:

  • Express: expressパッケージは、HTTPリクエストを処理するために必要です。
  • Sharp: sharpパッケージは、アップロードされた画像をサムネイルを含むさまざまなサイズで表示するために必要です。
  • Multer: multerパッケージは、Expressアプリケーションでファイルアップロードを処理するために必要です。
  • Catalyst SDK: AppSailサービスで必要なSDKメソッドを使用するために必要です。
copy
$
npm install express path zcatalyst-sdk-node@3.0.0-beta.3 multer sharp

catalyst_tutorials_photostore_stratus_install_backend_pack

次に、必要なバックエンドロジックを実装するために、以下のファイルにコードを追加します。

PhotoStoreApp/server/ディレクトリのserverフォルダにある以下のファイルにコードを追加します:

  • index.js: このファイルには、画像のサムネイル変換、すべての画像の取得、すべての共有画像の取得など、さまざまなアプリケーション機能を実装するために必要なAPIが含まれます。
  • helperfunction.js: このファイルには、index.jsファイルで詳述されているプロセスを完了するために必要なヘルパー関数が含まれます。

以下の表は、このアプリケーションのバックエンドロジックを示しています。

アプリケーション機能 index.jsに含まれるAPI helperfunction.jsに含まれる関数
画像をリサイズしてサムネイルとしてアップロード /convertToThumbnailAndUpload uploadToStratus()
バケットから必要な画像を取得 /fetchAllImages listMyObjects()
共有画像のみを取得 /getSharedImages listSharedObjects()
listMyObjects()

以下のコードをコピーして、IDEを使用してプロジェクトのそれぞれのファイルに貼り付け、ファイルを保存してください。

注: このセクションのコードを確認して、十分に理解していることを確認してください。
index.js
copy
'use strict';
const express = require('express');
const path = require('path');
let catalyst = require('zcatalyst-sdk-node');
const multer = require("multer");
const helperFunctions = require('./helper-functions');
const app = express();
const appDir = path.join(__dirname, '../photo-store-app');
const port = process.env.X_ZOHO_CATALYST_LISTEN_PORT || 9000;
app.use(express.json());
app.use(express.static(appDir));
const upload = multer({ dest: "uploads/" });
app.get('/', function (req, res) {
  res.sendFile(path.join(appDir, 'index.html'));
});
app.post("/convertToThumbnailAndUpload", upload.single("image"), async (req, res) => {
  try {
    const obj = catalyst.initialize(req, { scope: 'admin' });
    const stratus = obj.stratus();
    const bucket = stratus.bucket("YOUR_BUCKET_NAME");
    const thumbnailName = req.file.originalname.substring(0, req.file.originalname.lastIndexOf("."));
    const inputPath = req.file.path;
    const zuid = req.body.id;
    console.log("ID: " + zuid);
    const thumbnailPath = `photos/thumbnails/${zuid}/`;
    let result;
    await helperFunctions.uploadToStratus(bucket, inputPath, thumbnailPath, thumbnailName)
      .then(resp => {
        console.log("Success");
        result = resp;
        res.json({ message: "Thumbnail created and uploaded successfully" });
      })
      .catch(error => {
        console.error("Error: " + JSON.stringify(error.message));
        res.status(500).json({ message: "Error Occurred" });
        return;
      });
  } catch (error) {
    console.log("Error in convertToThumbnailAndUpload API: " + error.message);
  }
});
app.get("/fetchAllImages", async (req, res) => {
  try {
    const obj = catalyst.initialize(req);
    const zuid = req.query.id;
    console.log("ID: " + zuid);
    const objPath = "photos/" + zuid;
    const stratus = obj.stratus();
    const bucket = stratus.bucket("YOUR_BUCKET_NAME");
    let resp = await helperFunctions.listMyObjects(bucket, objPath);
    res.json(resp);
  } catch (error) {
    console.error("Error at fetchAllImages API... ", error.message);
    res.status(500).send({ error: "An error occurred while fetching images." });
  }
});
app.get('/getAllUsers', async (req, res) => {
  try {
    const app = catalyst.initialize(req, { scope: "user" });
    const appAdmin = catalyst.initialize(req, { scope: "admin" });
    const userManagementAdmin = appAdmin.userManagement();
    const userManagements = app.userManagement();
    let allUserPromise = userManagementAdmin.getAllUsers();
    let currentUserPromise = userManagements.getCurrentUser();
    let details;
    let currentUser;
    await allUserPromise.then(allUserDetails => {
      details = allUserDetails;
    }).catch(err => {
      console.log("Error: " + err.message);
    });
    await currentUserPromise.then(details => {
      currentUser = details.email_id;
    }).catch(err => {
      console.log("Error: " + err.message);
    });
    const userDetails = details.map(id => ({
      zuid: id.zuid,
      mailId: id.email_id,
      name: id.first_name
    }));
    const otherUsers = userDetails.filter(user => user.mailId !== currentUser);
    res.send(otherUsers);
  } catch (error) {
    console.error("Error in getAllUsers API: " + JSON.stringify(error.message));
    res.status(500).send({ error: "An error occurred while fetching details." });
  }
});
app.post('/shareDetails', async (req, res) => {
  try {
    const app = catalyst.initialize(req);
    let zcql = app.zcql();
    let query = `SELECT COUNT(ImageShareDetails.BucketPath) FROM ImageShareDetails WHERE BucketPath = '${req.body.imagePath}' AND UserZuid = '${req.body.zuid}'`;
    let result = await zcql.executeZCQLQuery(query);
    let isPresent = result[0].ImageShareDetails["COUNT(BucketPath)"];
    if (isPresent == 0) {
      let rowData = {
        UserName: req.body.userName,
        BucketPath: req.body.imagePath,
        UserZuid: req.body.zuid,
        IsUpdate: req.body.isUpdate,
        SharedBy: req.body.sharedBy
      };
      let datastore = app.datastore();
      let table = datastore.table('ImageShareDetails');
      let insertPromise = table.insertRow(rowData);
      insertPromise.then((row) => {
        console.log("Inserted Row: " + row);
      }).catch((err) => {
        console.error("Error: " + err.message);
      });
      res.json({ message: "Access Provided" });
    } else {
      res.json({ message: "Image Already Shared" });
    }
  } catch (error) {
    console.error("Error in shareDetails API: " + error.message);
    res.status(500).send({ message: "Error Occurred" });
  }
});
app.get('/getSharedImages', async (req, res) => {
  try {
    const obj = catalyst.initialize(req);
    const zuid = req.query.id;
    const objPath = "photos/" + zuid;
    const stratus = obj.stratus();
    const bucket = stratus.bucket("YOUR_BUCKET_NAME");
    const zcql = obj.zcql();
    let resp = await helperFunctions.listSharedObjects(bucket, objPath, zcql, zuid);
    res.json(resp);
  } catch (error) {
    console.error("Error in getSharedImages API: " + error.message);
    res.status(500).json({ message: "Error Occurred" });
  }
});
app.get('/getSharedDetails', async (req, res) => {
  try {
    const obj = catalyst.initialize(req);
    const zuid = req.query.id;
    let zcql = obj.zcql();
    let query = `SELECT * FROM ImageShareDetails WHERE SharedBy = '${zuid}'`;
    let data = await zcql.executeZCQLQuery(query);
    const result = data.map(item => ({
      UserName: item.ImageShareDetails.UserName,
      IsUpdate: item.ImageShareDetails.IsUpdate,
      BucketPath: item.ImageShareDetails.BucketPath,
      UserId: item.ImageShareDetails.UserZuid
    }));
    res.send(result);
  } catch (error) {
    console.error("Error in getSharedDetails API: " + error.message);
    res.status(500).json({ message: "Error Occurred" });
  }
});
app.patch('/updateSharedDetails', async (req, res) => {
  try {
    const obj = catalyst.initialize(req);
    const isRevoke = req.body.RevokeAccess;
    const zuid = req.body.UserId;
    const isUpdate = req.body.IsUpdate;
    const bucketPath = req.body.BucketPath;
    let zcql = obj.zcql();
    let query;
    if (isRevoke == "yes") {
      query = `DELETE FROM ImageShareDetails WHERE UserZuid = '${zuid}' AND BucketPath = '${bucketPath}'`;
    } else {
      query = `UPDATE ImageShareDetails SET IsUpdate = ${isUpdate} WHERE UserZuid = '${zuid}' AND BucketPath = '${bucketPath}'`;
    }
    let data = await zcql.executeZCQLQuery(query);
    res.json({ message: "Updated Successfully" });
  } catch (error) {
    console.error("Error in updateSharedDetails API: " + error);
    res.status(500).json({ message: "Error Occurred" });
  }
});
app.listen(port, () => {
  console.log(`Example app listening on port ${port}`);
});
View more
注: 20行目、49行目、127行目にバケット名を指定してください。
helper-function.js
copy
const sharp = require("sharp");
async function listMyObjects(bucket, prefix, isEdit = true) {
  try {
    const objects = await bucket.listPagedObjects({ prefix: prefix });
    let result = [];
    for (let i = 0; i < objects.contents.length; i++) {
      const objDetails = JSON.parse(objects.contents[i]);
      const imgInfo = {
        key: objDetails.key,
        object_url: objDetails.object_url,
        isEditAccess: isEdit
      };
      result.push(imgInfo);
    }
    return result;
  } catch (error) {
    console.error("Error at listMyObjects function: " + error);
  }
}
async function uploadToStratus(bucket, inputPath, thumbnailPath, thumbnailName) {
  try {
    const streamData = await sharp(inputPath)
      .resize({ width: 150, height: 150 })
      .toFormat("jpeg", { quality: 70 })
      .toBuffer();
    const result = await bucket.putObject(
      thumbnailPath + thumbnailName + ".jpeg",
      streamData
    );
    console.log("uploadToStratus method Completed");
    return result;
  } catch (error) {
    console.error("Error Occurred..." + JSON.stringify(error));
    throw { message: "Error in uploading", code: 500 };
  }
}
async function listSharedObjects(bucket, prefix, zcql, zuid) {
  try {
    let query = `SELECT * FROM ImageShareDetails WHERE UserZuid = ${zuid}`;
    let result = await zcql.executeZCQLQuery(query);
    const queryData = result.map(item => ({
      path: item.ImageShareDetails.BucketPath,
      isEdit: item.ImageShareDetails.IsUpdate
    }));
    let allSharedImages = [];
    for (const item of queryData) {
      const result = await listMyObjects(bucket, item.path, item.isEdit);
      allSharedImages.push(result);
    }
    return allSharedImages;
  } catch (error) {
    console.error("Error Occurred..." + error.message);
  }
}
module.exports = {
  listMyObjects,
  uploadToStratus,
  listSharedObjects
};
View more

最終更新日 2026-02-23 18:09:41 +0530 IST