nkjmkzk.net

powered by Kazuki Nakajima

Archive for 1月, 2014

HTML5アプリのプラットフォームとして最高なForce.com

僕はHTML5アプリを開発するプラットフォームとしてForce.comは極めて優れた、心地よい開発基盤だと考えています。何故か?

API First

モダンなWebサービスではバックエンド(データベース)側にAPIを整備し、フロントエンド(UI)は一貫してAPIを通じてバックエンドとやりとりするという構成が少なくありません。特にHTML5アプリではユーザーの操作に応じて適宜Ajaxコールをおこない画面を動的に生成していきます。

Force.comではオブジェクト(テーブル)を作成すると、そのオブジェクトに対するREST APIが自動的に作成されます。そのため開発者はバックエンドにAPIを整備する必要がありません。オブジェクトを作成すればすぐにフロントエンドから突っつくことができます。

api_centirc_architecture

Javascript Remoting

バックエンドのAPIはJavascriptから簡単にコールできます。Force.comではJavascript Remotingという仕組みでバックエンドのAPIをJavascriptのメソッドにマッピングすることができるため、開発者は対応するメソッドを実行するだけでAPIをコールできます。Javascriptは僕がForce.comの中で最も気に入っている機能の一つです。

豊富なサンプル

Webアプリの開発は数多あるライブラリの活用なしには考えられない時代です。AngularJS, jQuery Mobile, Backbone.js, Knockout.jsといったライブラリは多くの開発者が愛して止まないものだと思います。

これらのライブラリをForce.comでどのように適用すればいいのか、すぐに始められるテンプレートが用意されています。これらのテンプレートはサンプルコードとしても大変有用です。

僕はすごいアンケートの最新バージョンの開発においてAngularJSとTwitter Bootstrapを活用してアプリケーション全体を再構築しました。特にユーザーインターフェースについてForce.com固有の機能はほとんど使っていません。HTML, CSS, Javascriptとオープンなライブラリを活用したHTML5アプリになっています。

Force.comはクリックベースでアプリケーションを開発する、あるいはVisualforceとApexという専用言語で開発するといった認識をお持ちの方がいるかもしれませんが、実際にはBaaSとしてHTML5アプリを開発するプラットフォームとして類例のない開発基盤だと思います。

Force.comは極めて多面的なプラットフォームです。前述の通り、標準画面を活用したクリックベースの高速開発もできますし、APIを中心としたHTML5アプリの開発、モバイルアプリの開発もおこなうことができます。これは全く異なる開発シナリオであり、どちらも「あり」だと思います。

クリックベースの開発事例は数えきれないほどあります。その点でForce.comの高速開発の価値は知られていますが、Force.comにはもう一つのBaaSとしての顔があり、これがたいそう優れモノなのです。

僕は日本でもっとAPI中心のForce.com開発を浸透させ、多くのHTML5アプリ、モバイルアプリがリリースされるように啓蒙を推し進めていこうと考えています。第一弾としてAngularJSを使ったForce.com開発入門を近々ブログにアップし、セミナーを実施しようと思っています。あー、楽しみだ。

without comments

Written by 中嶋 一樹

1月 22nd, 2014 at 12:43 pm

Posted in Uncategorized

Tagged with , ,

Force.comでオブジェクト権限・項目権限に準じたCRUDをおこなうライブラリ

Force.comにおいて、Apexコードはシステム権限で動作するので、実行ユーザーに依らずすべてのデータにアクセスできます。

しかしAppExchangeに公開されるアプリケーションはユーザーに割り当てられたオブジェクト権限・項目権限を遵守する必要がります。そのためにはApexコード内でデータベースにアクセスする際、実行ユーザーにその権限があるかどうかチェックする必要があります。

public with sharing class employee {
    private class sexception extends exception {}

    public void updateEmployee(id, e_id, string e_name, integer e_salary){
        if (!Schema.sObjectType.employee__c.fields.Name.isUpdateable()){
            sexception e = new sexception();
            e.setMessage('Field Name is not updateable.');
            throw e;
        }
        if (!Schema.sObjectType.employee__c.fields.salary__c.isUpdateable()){
            sexception e = new sexception();
            e.setMessage('Field Salary__c is not updateable.');
            throw e;
        }
        employee__c emp = [select Id from employee__c where Id = :e_id for update];
        emp.Name = e_name;
        emp.salary__c = salary;
        update emp;
    }
}

上記のApexクラスでは、employee__cというオブジェクトに対して更新処理をおこなうメソッドupdateEmployee()が定義されています。更新処理(18行目 update emp)の前にSchema.sObjectType.employee__c.fields.Name.isUpdateable()といった形で、フィールド毎に更新権限の有無を確認しています。

このコードは権限チェックにおいて最も原始的な処理方法です。この方法にはいくつか問題があります。

  • DML操作の前に、更新する項目を網羅的に指定してチェックをおこなう必要がある。
  • 一項目をチェックするとガバナ制限のfield describeメソッドの制限(トランザクション内最大100回)に対してカウントされるため、多くの項目がある場合ガバナ制限に抵触する可能性が高い。

上記の問題点を解決するために権限チェックのコードを汎用化・効率化する必要があり、それらをこちらのライブラリにまとめました。

https://github.com/nkjm/scrud

前述の更新処理は、このscrudライブラリを用いると下記のように記述できます。

public with sharing class employee {
    private class sexception extends exception {}

    public void updateEmployee(id, e_id, string e_name, integer e_salary){
        employee__c emp = [select Id from employee__c where Id = :e_id for update];
        emp.Name = e_name;
        emp.salary__c = salary;
        scrud.supdate(emp);
    }
}

チェック処理はすべてライブラリに任せることができ、更新する項目も自動的に検出されるため、明示的に指定する必要がありません。また、項目数に依存せずupdateであればfield describeのガバナ制限に対して一回しかカウントされません。

このscrud.supdate()は引数にオブジェクトまたはオブジェクトのリストをとります。なので実質的にはupdateをscrud.supdateに置き換えるだけでApexコードをオブジェクト・項目権限に遵守させることができます。ちなみに insert / update / delete は下記の通りすべて同じマナーで利用することができます。

  • insert => scrud.sinsert()
  • update => scrud.supdate()
  • delete => scrud.sdelete()

また、updateに関しては更新できない項目がオブジェクトに含まれていた場合の挙動を選択することができます。デフォルトでは更新できる項目のみが更新され、更新できない項目が含まれていてもエラーにはなりません。更新権限のない項目があった場合にオブジェクトの更新を中止して例外を発生させるには第二引数にtrueを指定します。

scrud.supdate(emp, true)

他にも、下記のようなメソッドが用意されています。

// 対象オブジェクト・項目への参照アクセス権限の有無を確認する
scrud.isAccessible(sObject object)
scrud.isAccessible(sObject object, list<string> fields)

// 対象オブジェクト・項目へアクセス権限がなければ例外を発生させる
scrud.requireAccessible(sObject object)
scrud.requireAccessible(sObject object, list<string> fields)

// 対象オブジェクトで権限のある項目をリストで取得する
scrud.getCreateableFields(string objectName)
scrud.getAccessibleFields(string objectName)
scrud.getUpdateableFields(string objectName)
scrud.getUpsertableFields(string objectName)

// 対象オブジェクトで権限のある項目をカンマ区切りの文字列で取得する(Dynamic SOQLに便利)
scrud.getCreateableFieldsInCSV(string objectName)
scrud.getAccessibleFieldsInCSV(string objectName)
scrud.getUpdateableFieldsInCSV(string objectName)
scrud.getUpsertableFieldsInCSV(string objectName)

Secure Codingのお役に立てば幸いです。

without comments

Written by 中嶋 一樹

1月 20th, 2014 at 4:50 pm

Posted in Uncategorized

Tagged with , ,