فراخوانی یک تابع - Android
در این بخش با چند مثال ساده نحوه اتصال به سرویس رایانش را شرح خواهیم داد.
پیشنیازها
- در صورتی که با سرویس رایانش آشنایی ندارید، به معرفی سرویس رایانش مراجعه کنید.
- در صورتی که هنوز با تنظیمات پنل سرویس رایانش آشنا نشدهاید و یک تابع در آن جا نساختهاید، به تنظیمات پنل رایانش مراجعه کنید.
- در صورتی که با سرویس کاربران آشنایی ندارید، به معرفی سرویس کاربران مراجعه کنید.
- در صورتی که هنوز SDK اندروید را راهاندازی نکردهاید، به راهاندازی SDK بکتوری در اندروید مراجعه کنید.
راهاندازی سرویس رایانش
پس از راهاندازی SDK اندروید در پروژه خود، در شروع اپلیکیشن بایستی SDK بکتوری را initialize کنید. در عمل initialize شما تمامی سرویسهایی که علاقهمند به استفاده هستید، را ذکر خواهید کرد. برای سرویس رایانش کدی مشابه زیر بایستی داشته باشید:
// Extending android application to initialize backtory
public class MainApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
// Initializing backtory
BacktoryClient.init(KeyConfiguration.newBuilder().
setAuthKeys("<X-Backtory-Authentication-Id>",
"<X-Backtory-Authentication-Key (Client)>").
// Enabling Cloud Code
setCloudcodeKey("<Cloud-Code-Id>").
// Finalizing sdk
build(), this);
}
}
به صورت کلی تمامی نیازمندیهای رایانش شما در اندروید از کلاس BacktoryCloudCode مرتفع میگردد. این کلاس به شما امکان اتصال به سرورهای بکتوری و فراخوانی کد در محیط ابری بکتوری را میدهد.
وظایف SDK بکتوری
سرویس رایانش همانطور که میدانید شامل تعدادی تابع است که منطق اپلیکیشن شما را در خود دارد. هر تابع یک نام یکتا دارد و با همان نام شناخته میشود، و میتواند بسته به منطقی که شما پیادهسازی کردهاید، دارای یک شیء (Object) ورودی و یک شیء خروجی باشد. SDK اندروید رایانش، جهت سهولت کار شما، تمامی جزییاتِ
- تبدیل و ارسال اشیا
- فراخوانی تابع
- دریافت جواب و تبدیل جواب به اشیا
را انجام میدهد و شما نیازی به درگیرشدن در این جزییات تکراری ندارید.
ایجاد یک مثال کاربردی
فرض کنید اپلکیشن شما یک فروشگاه آنلاین است و تابعی که شما قصد فراخوانی آن را دارید موجودی یک کالا را در سرور چک میکند و به شما خبر میدهد که آیا امکان خرید آن را دارید یا نه. تصور کنید که نام این تابع check_availability است و شما کدی مشابه زیر را در سرویس رایانش (در پنل وبسایت بکتوری) برای آن نوشتهاید:
// import backtory sdk for real usage, not in this example
var Backtory = require('backtory-sdk');
// Body of code in server
exports.handler = function(requestBody, context) {
// Step 1: extract data from request
var requestedCount = requestBody.count;
var productId = requestBody.id;
// Step 2: your logic here
// TODO: Query to database if product is available for sale
var isAvailable = requestedCount < 10 && productId == 'iPhone 6 Plus 64GB' ? true : false;
// TODO: Query to database for price of product
var unitPrice = productId == 'iPhone 6 Plus 64GB' ? 26000000 : -1;
// Step 3: send result to android device
context.succeed({
ok: isAvailable,
price: unitPrice
});
};
کد بالا سه کار زیر را انجام میدهد:
- از ورودی (requestBody) دو مقدار count و id را دریافت میکند. این دو فیلد توسط شما از اپلیکیشن خرید ارسال میشود. فیلد id نشان میدهد که قصد خرید چه کالایی را دارید و فیلد count نشانگر تعداد مورد نیاز شماست.
- کد رایانش باید به پایگاهداده پروژه شما در بکتوری وصل شود و موجودی کالای درخواستی را بررسی کند. در مثال بالا، کد ساده ما چک میکند در صورتی که درخواست برای آیفون ۶۴ گیگابایتی باشد و تعداد درخواستی هم کمتر از ۱۰ عدد باشد پاسخ OK میدهد. قیمت واحد کالا هم در کد بالا در صورتی که آیفون ۶۴ گیگابایتی باشد برابر دو میلیون و ششصد هزار تومان و در غیر این صورت نامشخص (1-) است.
- در پاسخ به درخواست اپلیکیشن پاسخی به کمک دستور context.succeed بازگردانده میشود که دو فیلد ok و price دارد که موجود بودن و قیمت واحد کالا را اعلام میکند.
در بخش بعدی از طریق اندروید به این تابع وصل شده و موجود را چک خواهیم کرد.
نحوه فراخوانی تابع از اندروید
در این بخش قصد داریم تابع بالا را فراخوانی کنیم. برای این کار ابتدا دو کلاس جاوا در کد اپلکیشن خود برای ورودی و خروجی تابع check_availability تعریف میکنیم.
کلاس درخواست:
public class ProductCheckRequest {
private String id;
private int count;
public ProductCheckRequest(String id, int count) {
setId(id);
setCount(count);
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
کلاس پاسخ:
public class ProductCheckResponse {
private boolean ok;
private long price;
public boolean isOk() {
return ok;
}
public void setOk(boolean ok) {
this.ok = ok;
}
public long getPrice() {
return price;
}
public void setPrice(long price) {
this.price = price;
}
}
حال به سادگی فراخوانی را انجام میدهیم:
// Create a request for TWO iphones, I am rich!
ProductCheckRequest requestForIphone = new ProductCheckRequest("iPhone 6 Plus 64GB", 2);
// Request server whether iphone is available or not
BacktoryCloudCode.runInBackground(
// Name of cloud code function
"check_availability",
// Request for iphone
requestForIphone,
// Type of response that server will return
ProductCheckResponse.class,
// Callback to handle result
new BacktoryCallBack<ProductCheckResponse>() {
@Override
public void onResponse(BacktoryResponse<ProductCheckResponse> response) {
if (response.isSuccessful()) // = context.succeed is called in server
// Extract ok and price from response
ProductCheckResponse result = response.body();
boolean ok = result.getOk();
long price = result.getPrice();
// Log the result
Log.d(TAG, "Can I buy it?: " + ok
+ ", how much should I pay for every iphone? " + price);
}
}
);
در صورت بروز خطا مقدار ()response.isSuccessful برابر false خواهد بود و عبارت ()response.code کد خطای اتفاق افتاده را شرح خواهد داد. مقدار این کد خطا یکی از مقادیر زیر است:
Tables | Description |
---|---|
200-OK | Function done successfully, aka context.succeed is called in server |
400-Bad Request | Something you sent to server is wrong |
401-Unauthorized | This function needs login before call |
402-Not Enough Credit | Your service is disabled in backtory, charge your account |
404-Not Found | Your initliazation key or function name is wrong |
420-Run Failed | Run failed, aka context.fail is call or execution timed-out |
500-Internal Server Error | Data access was unsuccessful |
503-Service Unavailable | Backtory is unavailable right now |
به این ترتیب به سادگی میتوانید یک منطق پیچیده را به سمت سرور انتقال دهید و به سادگی و تمیز آن را در سمت اندروید فراخوانی کنید.
امنیت کاربران در رایانش
معمولا شما در منطق برنامه خود برای حفظ امنیت، نیاز دارید که کاربران را شناسایی کنید. برای مثال، فرض کنید در مثال فروشگاه آنلاین ما هر کاربر یک کیف پول مجازی دارد و قصد خرید کالا دارد. در فرآیند خرید در صورتی که کیف پول مجازی کاربر موجودی کافی داشته باشد، آن کالا خریداری شده و موجودی حساب کاربر شما کم خواهد شد. در این مثال شما در سمت کد رایانش باید بدانید تابع خرید (purchase) برای چه کاربری از مجموعه کاربران شما است. در صورتی که مثلا شناسه یا نام کاربری را از ورودی (requestBody) دریافت کنید، کد شما دچار ایراد امنیتی خواهد بود. زیرا هر کاربر دیگری میتواند در requestBody نامکاربری یک کاربر دیگر را وارد کند و عملا کاربر دوم، بدون هیچ اطلاعی، پول مجازی خود را از دست خواهد داد.
راهکار بکتوری استفاده از سرویس کاربران است. در صورتی که کاربر شما در اپلیکیشن ورود کرده باشد، SDK رایانش به طور اتوماتیک بدون آنکه نیاز باشد کاری کنید، اطلاعات کاربر را به صورت امن به دست کد رایانش شما در سرور میرساند. شما کافیست در کد سرور آیدی کاربر را دریافت کرده و چکهای منطقی لازم را انجام دهید. در این مدل هیچ کاربری نمیتواند خود را به جای کاربر دیگری قرار دهد و تقلب کند.
همانطور که گفتیم شما لازم به انجام هیچکاری در اندروید نیستید و در سمت سرور نیز تکه کد زیر نامکاربری و شناسه کاربر را چاپ میکند:
// Body of code in server
exports.handler = function(requestBody, context) {
// Get userId from security context
var userId = context.getSecurityContext().userId;
// Get userName from security context
var userName = context.getSecurityContext().userName;
// print user info to response
context.succeed('request is originally sent from: ' + userName + ' with id: ' + userId);
};
به این ترتیب شما میتوانید همه منطق اپلیکیشن خود را آنلاین کنید و با استفاده از SDK رایانش به صورت کاملا امن آنها را فراخوانی کنید.