کار با اشیاء - REST

نکته: در صورتی که با مفهوم REST و سرویس‌های سمت سرور و یا با دستور curl آشنایی ندارید، به آشنایی با REST مراجعه کنید.

پیش‌نیازها

  1. در صورتی که با سرویس پایگاه‌داده آشنایی ندارید، به معرفی سرویس پایگاه‌داده مراجعه کنید.
  2. در صورتی که هنوز در پنل توسعه‌دهنده خود تنظیمات لازم برای سرویس پایگاه‌داده خود را انجام نداده‌اید، به تنظیمات پنل مراجعه کنید.
  3. در صورتی که با سرویس کاربران بکتوری آشنایی ندارید و فرآیندهای امنیتی بکتوری را نمی‌شناسید، به معرفی سرویس کاربران مراجعه کنید.

توجه: در همه درخواست‌ها مقدار هدر X-Backtory-Object-Storage-Id باید از صفحه پروژه، بخش کلیدها استخراج و دریافت شود.

اضافه کردن شیء به پایگاه‌داده

اضافه کردن داده‌ها به پایگاه داده از طریق پنل گرچه ساده است، اما بسیار زمان‌بر است و بهتر است که بتوانیم با برنامه‌نویسی به صورت خودکار داده‌ها (همان سطرها) را در پایگاه داده قرار دهیم. به عنوان مثال، پیشتر ما جدولی به نام Player برای ذخیره اطلاعات یک بازیکن فوتبال ساخته‌ایم. این جدول یک ستون برای اسم بازیکن به نام name از نوع String، یک ستون به نام score و از نوع Number برای ذخیره امتیاز بازیکن، و یک ستون هم به نام age و از نوع Number برای نگهداری سن بازیکن دارد. برای اضافه کردن یک سطر به این جدول می‌توانیم یک سرویس REST فراخوانی کنیم:

curl -X POST \
    --header 'Authorization: Bearer <user-access-token>' \
    --header 'X-Backtory-Object-Storage-Id: <object-storage-Id>' \
    --header "Content-Type: application/json" \
    -d 	'{
            "name" : "Ali Daei",
            "score" : 20,
            "age" : 27
         }' \
    https://api.backtory.com/object-storage/classes/Player/

در این درخواست، header مربوط به X-Backtory-Object-Storage-Id را می‌توانید از روی پنل مدیریت خود مشاهده کنید و header مربوط به Authorization با access-token دریافت شده از درخواست ورود (سرویس کاربران) تکمیل می‌شود و مشخص می‌کند که چه کاربری درخواست اضافه شدن این سطر به جدول {Table-Name} را کرده است. با توجه به مثال بالا لازم است که به جای {Table-Name} نام جدول یعنی Player را قرار دهیم.

درخواست بالا یک سطر در جدول Player می‌سازد. پاسخ این درخواست یک شیء JSON مانند زیر است:

{
    "createdAt": "2012-04-28T17:41:09.106Z",
    "_id": "165632938928392"
}

از این پاسخ پیداست که یک سطر با id برابر 165632938928392 ساخته شده است که تاریخ ساخت آن در فیلد createdAt آمده است. در صورت عدم موفقیت، می‌توانیم با استفاده از کد وضعیتی که در پاسخ درخواست آمده علت را متوجه شویم:

Tables Description
201-Created Object was created successfully
400-Bad Request Your request syntax is not correct
401-Unauthorized User is not authorized
403-Forbidden Permission is denied for creation
404-Not Found A required resource like {tableName} not found
500-Internal Server Error Backtory server failed to respond

ویرایش شیء در پایگاه داده

اگر بخواهیم در داده‌ای که پیشتر در پایگاه داده ساخته شده است، تغییری ایجاد کنیم و آن را ویرایش کنیم، از این سرویس استفاده می‌کنیم. برای این منظور با فراخوانی یک سرویس REST یک درخواست PUT به شکل زیر ارسال می‌کنیم .در این درخواست تنها اطلاعات ستون‌هایی را که می‌خواهیم ویرایش شوند، در بدنه درخواست ارسال می‌کنیم.

curl -X PUT \
    --header 'Authorization: Bearer <user-access-token>' \
    --header 'X-Backtory-Object-Storage-Id: <object-storage-Id>' \
    --header "Content-Type: application/json" \
    -d '{"name" : "Ali Karimi"}' \
    https://api.backtory.com/object-storage/classes/Player/{Object-Id}

در این درخواست، header مربوط به X-Backtory-Object-Storage-Id را می‌توانید از روی پنل مدیریت خود مشاهده کنید و header مربوط به Authorization با access-token دریافت شده از درخواست ورود (سرویس کاربران) تکمیل می‌شود و مشخص می‌کند که چه کاربری درخواست ویرایش سطر با Id برابر با {Object-Id} را در جدول {Table-Name} کرده است.

با توجه به مثال بازیکنان فوتبال لازم است که به جای {Table-Name} نام جدول یعنی Player را قرار دهیم و {Object-Id} در واقع Id سطری از جدول است که قصد تغییرش را داریم. این id در پاسخ به درخواست مربوط به ساختن این شیء برگردانده شده است. نمونه‌ای از پاسخ دریافت شده پس از ارسال این درخواست عبارت است از:

{
    "updatedAt": "2011-08-21T18:02:52.248Z"
}

کدهای پاسخی که این سرویس ممکن است در پاسخ بدهد به صورت جدول زیر است:

Tables Description
200-Created Object was edited successfully
400-Bad Request Your request syntax is not correct
401-Unauthorized User is not authorized
403-Forbidden Permission is denied for creation
404-Not Found A required resource like {tableName} not found
500-Internal Server Error Backtory server failed to respond

شمارنده

برای کمک به ذخیره داده های از نوع شمارشی، بکتوری امکان افزایش اتمی (یا کاهش) هر فیلد شمارشی را فراهم می‌کند. بنابراین، می توانیم فیلد نمره را به صورت زیر افزایش دهیم:

curl -X PUT \
    --header 'Authorization: Bearer <user-access-token>' \
    --header 'X-Backtory-Object-Storage-Id: <object-storage-Id>' \
    --header "Content-Type: application/json" \
    -d '{"score":{"__op":"Increment","amount":1}}' \
    https://api.backtory.com/object-storage/classes/Player/{Object-Id}

برای کاهش شمارنده نیز می‌توان از همان اپراتور Increment با مقدار منفی استفاده کرد. یعنی:

curl -X PUT \
    --header 'Authorization: Bearer <user-access-token>' \
    --header 'X-Backtory-Object-Storage-Id: <object-storage-Id>' \
    --header "Content-Type: application/json" \
    -d '{"score":{"__op":"Increment","amount":-1}}' \
    https://api.backtory.com/object-storage/classes/Player/{Object-Id}

آرایه‌ها

برای کمک به ذخیره داده های آرایه، سه عملیات وجود دارد که می توان آن را به صورت اتمی تغییر داد:

هر روش یک آرایه از اشیاء را برای اضافه کردن یا حذف در کلید “objects” می گیرد. به عنوان مثال، ما می توانیم موارد زیر را به فیلد “skills” به صورت یکتا اضافه کنیم:

 curl -X PUT \
     --header 'Authorization: Bearer <user-access-token>' \
     --header 'X-Backtory-Object-Storage-Id: <object-storage-Id>' \
     --header "Content-Type: application/json" \
     -d '{"skills":{"__op":"AddUnique","objects":["flying","kungfu"]}}' \
     https://api.backtory.com/object-storage/classes/Player/{Object-Id}

رابطه‌ها

به منظور به روز رسانی انواع Relationها، بکتوری اپراتورهای ویژه‌ای را برای اضافه کردن و حذف اشیاء به یک رابطه به صورت اتمی فراهم می کند. بنابراین، می توان یک شی را به یک رابطه به صورت زیر اضافه کرد:

   curl -X PUT \
       --header 'Authorization: Bearer <user-access-token>' \
       --header 'X-Backtory-Object-Storage-Id: <object-storage-Id>' \
       --header "Content-Type: application/json" \
       -d '{"games":{"__op":"AddRelation","objects":
       [{"__type":"Pointer","className":"Game","_id":"165632938928345"}]}}' \ \
       https://api.backtory.com/object-storage/classes/Player/{Object-Id}

برای حذف یک شی از رابطه نیز، می‌توانید بدین صورت عمل کنید:

   curl -X PUT \
       --header 'Authorization: Bearer <user-access-token>' \
       --header 'X-Backtory-Object-Storage-Id: <object-storage-Id>' \
       --header "Content-Type: application/json" \
       -d '{"games":{"__op":"RemoveRelation","objects":
       [{"__type":"Pointer","className":"Game","_id":"165632938928345"}]}}' \ \
       https://api.backtory.com/object-storage/classes/Player/{Object-Id}

گرفتن جزئیات یک شیء

ممکن است بخواهید از طریق id داده‌ی ذخیره شده به تمامی جزئیات آن شیء دسترسی پیدا کنید. id به دست آمده پس از ساخت یک شیء در پایگاه داده را در انتهای آدرس (url) قرار دهید و درخواستی با فرمت زیر ارسال کنید:

curl -X GET \
    --header 'Authorization: Bearer <user-access-token>' \
    --header 'X-Backtory-Object-Storage-Id: <object-storage-Id>' \
    https://api.backtory.com/object-storage/classes/{Table-Name}/{Object-Id}

در این درخواست، header مربوط به X-Backtory-Object-Storage-Id را می‌توانید از روی پنل مدیریت خود مشاهده کنید و header مربوط به Authorization با access-token دریافت شده از درخواست ورود (سرویس کاربران) تکمیل می‌شود و مشخص می‌کند که چه کاربری درخواست دریافت سطر با Id برابر با {Object-Id} را در جدول {Table-Name} کرده است.

با توجه به مثال بازیکن فوتبال لازم است که به جای {Table-Name} نام جدول یعنی Player را قرار دهیم و {Object-Id} در واقع Id سطری از جدول است که قصد دریافتش را داریم. این id در پاسخ به درخواست مربوط به ساختن این شیء برگردانده شده است. در پاسخ برگردانده شده کل شیء با جزئیات آن برگردانده می‌شود. نمونه‌ای از پاسخ دریافت شده از این درخواست عبارست است از:

{
    "_id": "57359470adbe1d000179f2ff",
    "name": "Ali Daei",
    "score": 103,
    "age": 43,
    "createdAt": "2016-05-13T08:46:40.294UTC",
    "updatedAt": "2016-06-17T10:53:13.040UTC",
    "ACL": {
        "*": {
            "read": true,
            "write": true
        }
    }
}

کدهای پاسخی که این سرویس ممکن است در پاسخ بدهد به صورت جدول زیر است:

Tables Description
200-Created Object was fetched successfully
400-Bad Request Your request syntax is not correct
401-Unauthorized User is not authorized
403-Forbidden Permission is denied for creation
404-Not Found A required resource like {tableName} not found
500-Internal Server Error Backtory server failed to respond

حذف یک سطر از پایگاه داده

برای حذف یک شیء یا سطر از پایگاه داده‌ می‌توانیم یک درخواست REST ارسال کنیم. این درخواست مشابه درخواست گرفتن جزئیات یک شیء است با این تفاوت که از نوع DELETE است:

curl -X DELETE \
    --header 'Authorization: Bearer <user-access-token>' \
    --header 'X-Backtory-Object-Storage-Id: <object-storage-Id>' \
    https://api.backtory.com/object-storage/classes/{Table-Name}/{Object-Id}

در این درخواست، header مربوط به X-Backtory-Object-Storage-Id را می‌توانید از روی پنل مدیریت خود مشاهده کنید و header مربوط به Authorization با access-token دریافت شده از درخواست ورود (سرویس کاربران) تکمیل می‌شود و مشخص می‌کند که چه کاربری درخواست حذف سطر با Id برابر با {Object-Id} را از جدول {Table-Name} کرده است.

با توجه به مثال بازیکن فوتبال لازم است که به جای {Table-Name} نام جدول یعنی Player را قرار دهیم و {Object-Id} در واقع Id سطری از جدول است که قصد حذفش را داریم. این id در پاسخ به درخواست مربوط به ساختن این شیء برگردانده شده است.

کدهای پاسخی که این سرویس ممکن است در پاسخ بدهد به صورت جدول زیر است:

Tables Description
200-Created Deleted successfully
400-Bad Request Your request syntax is not correct
401-Unauthorized User is not authorized
403-Forbidden Permission is denied for creation
404-Not Found A required resource like {tableName} not found
500-Internal Server Error Backtory server failed to respond

حذف تمامی سطرهای یک جدول

برای پاک کردن کل سطرهای یک جدول از پایگاه داده‌ می‌توانیم یک درخواست REST به صورت زیر ارسال کنیم که مشابه درخواست حذف یک سطر از جدول است با این تفاوت که نیازی به تعیین شناسه‌ی خاصی برای حذف آن سطرها نیست:

curl -X DELETE \
    --header 'Authorization: Bearer <MASTER-ACCESS-TOKEN>' \
    --header 'X-Backtory-Object-Storage-Id: <object-storage-Id>' \
    https://api.backtory.com/object-storage/classes/{Table-Name}

در پاسخ این درخواست نیز جوابی به صورت زیر داده می‌شود که بیانگر تعداد سطرهای حذف شده از جدول موردنظر است. دقت کنید که این کار فقط با دسترسی master قابل انجام است.

{ 
    "deletedCount": 15
}

اجرای کوئری بر روی مجموعه داده‌ها

در صورتی که بخواهیم با فراخوانی یک سرویس REST یک کوئری را اعمال کنیم (مثلا داده‌های خاصی را استخراج کنیم)، ابزارهای بیشتری برای اعمال شرط گذاری نسبت به استفاده از پنل در اختیارمان گذاشته می‌شود. نمونه این درخواست در زیر آمده است

curl -X POST \
    --header 'Authorization: Bearer <user-access-token>' \
    --header 'X-Backtory-Object-Storage-Id: <object-storage-Id>' \
    --header "Content-Type: application/json" \
    -d '{
            "age" : {
                "$gt" : 20,
                "$lt" : 25
            }
        }' \
    https://api.backtory.com/object-storage/classes/query/Player

در این درخواست، header مربوط به X-Backtory-Object-Storage-Id را می‌توانید از روی پنل مدیریت خود مشاهده کنید و header مربوط به Authorization با access-token دریافت شده از درخواست ورود (سرویس کاربران) تکمیل می‌شود و مشخص می‌کند که چه کاربری درخواست اعمال کوئری بر جدول Player را دارد. بدنه این درخواست یک کوئری Mongodb است که به شما امکان می‌دهد کوئری دلخواه خود را بر روی پایگاه داده خود اجرا کنید و نتیجه آن را ببینید.

عملیات های Batch

ارسال هر درخواست دارای سربار زمانی است که در شبکه صرف ارسال درخواست و دریافت پاسخ می‌شود. به عنوان مثال فرض کنید سربار شبکه ۲۰ میلی ثانیه باشد و بخواهید ۱۰۰۰ سطر در یک جدول ایجاد کنید. اگر برای این‌کار به ازای هر سطر، یک درخواست ارسال کنید، سربار شبکه‌ای که متحمل می‌شوید، ۲۰ ثانیه است. اگر راهی باشد که در هر درخواست، ۱۰۰ سطر را ایجاد کنید، می‌توانید کل سربار شبکه را به ۰.۲ ثانیه کاهش دهید.

برای کاهش زمان مصرف شده در شبکه، سرویس دیتابیس به شما امکان می‌دهد که بیش از یک عملیات را در یک درخواست از نوع batch قرار دهید. این درخواست‌ها می‌توانند از نوع ساختن، به‌روز‌رسانی، یا حذف سطر از جدول باشند.

هر دستور در یک درخواست Batch شامل پارامترهای method، path، و body است که در حقیقت دستور HTTP ایکه به صورت عادی استفاده می‌شود را مشخص می‌کند. این دستورها به ترتیبی که ارسال می‌شوند، اجرا می‌شوند. به عنوان مثال برای ساخت تعدادی بازیکن در جدول Player می‌توانیم این درخواست را ارسال کنیم:

curl -X POST \
    --header 'Authorization: Bearer <user-access-token>' \
    --header 'X-Backtory-Object-Storage-Id: <object-storage-Id>' \
    --header "Content-Type: application/json" \ 
    -d '{ 
            "requests": [ 
                { "method": "POST", "path": "/classes/Player", "body": 
                { "Name": "Sean Plott" } }, 
                { "method": "POST", "path": "/classes/Player", "body": 
                { "Name": "ZeroCool" } } 
            ]
        }' \ 
    https://api.backtory.com/object-storage/batch

پاسخ این درخواست شامل لیستی به اندازه همان لیست ورودی است. آیتم‌های این لیست به همان ترتیب ورودی پاسخ مربوطه هستند. هر پاسخ موفق با کلید success و هر پاسخ مربوط به عملیاتی که به خطا خورده با کلید error می‌‌آید. مقدار مرتبط با کلید success همان پاسخ عادی است که اگر درخواست را به طور مجزا می‌زدیم داشتیم:

{ 
    "success": { 
        "createdAt": "2012-06-15T16:59:11.276Z", 
        "_id": "32655326546356453" 
    } 
}

مقدار مربوط به کلید error یک شیء با دو کلید عددی code و رشته‌ای error است:

{ 
    "error": { 
        "code": 404, 
        "error": "no schema with name <?> exists in application with id <?>" 
    } 
}

دیگر دستوراتی که به صورت Batch اجرا می‌شوند عبارتند از Update و Delete. در مثالی که در ادامه می‌آید دو عملیات یکی از نوع حذف و دیگری از نوع به‌روزرسانی قرار دارد:

curl -X POST \ 
    --header 'Authorization: Bearer <user-access-token>' \
    --header 'X-Backtory-Object-Storage-Id: <object-storage-Id>' \
    --header "Content-Type: application/json" \
    -d '{
            "requests": [
                {
                    "method": "PUT",
                    "path": "/classes/{Table-Name}/{Object-Id}",
                    "body": { "score": 999999 }
                },
                {
                    "method": "DELETE",
                    "path": "/classes/{Table-Name}/{Object-Id}"
                }
            ]
        }' \
    https://api.backtory.com/object-storage/batch

در ادامه پس از بررسی انواع داده‌هایی که در پایگاه داده می‌توانید ذخیره کنید، امکانات پیشرفته‌ای که این سرویس در اختیار شما قرار می‌دهد را بررسی می‌کنیم.

گام بعدی