.NET の概念の Lightning プラットフォームへの対応付け
学習の目的
この単元を完了すると、次のことができるようになります。
- Lightning プラットフォームを構成する主要な機能と Apex プログラミング言語を理解する
- .NET と Lightning プラットフォームの類似点と相違点を識別する
- 開発者コンソールを使用して最初の Apex クラスを作成する
- 匿名 Apex を使用して Apex クラスからメソッドを呼び出す
一緒にトレイルを進みましょう
エキスパートの説明を見ながらこのステップを実行したい場合は、次の動画をご覧ください。これは「Trail Together」(一緒にトレイル) シリーズの一部です。
Lightning プラットフォームの概要
Lightning プラットフォームを理解するほど、その良さがわかるようになります。このモジュールでは、すでによく知っている .NET の概念を Lightning プラットフォームとどう関連付けるかを学習します。
プラットフォームの基本
まず、Lightning プラットフォームが具体的に何で構成されるかを簡単に確認しましょう。Force.com プラットフォームと他の SaaS (Software-as-a-Service) 製品との違いの 1 つは、メタデータ駆動型アーキテクチャに依存している点です。コード、設定、アプリケーションなど、すべてがメタデータとして指定されます。
.NET 開発者の皆さんは、おそらくすでに Microsoft Azure で実行されているクラウドアプリケーションについて詳しくご存じでしょう。Lightning プラットフォームの動作は異なります。Lightning プラットフォームはデータベースと緊密に統合されています。ユーザーインターフェース、セキュリティ、レポートなどさまざまな機能もプラットフォームに直接組み込まれています。この統合によって、アプリケーションをごく短期間で作成できます。
ただし、開発者の生産性を高めるためのコントロールができない部分があり、最初は少し違和感があるかもしれません。Lightning プラットフォームでは、ノードや管理タスクの設定について心配する必要がありません。あらゆるアップグレード、調整、拡張についても心配は不要です。実際には、優れたアプリケーションをすばやく作成することだけに専念できるので、こうした複雑さや作業をそれほど懐かしくは思わないでしょう。
このプラットフォームが提供する機能の概要をざっと確認しました。アーキテクチャについてさらに知識を深める場合は、「プラットフォームの基本」モジュールを参照してください。
Apex の基本
Lightning プラットフォームはメタデータアーキテクチャに緊密に統合され、依存しているため、宣言型開発、つまり「ポイント & クリック」アプリケーション開発を使用して実に多くの機能を実現できます。Lightning プラットフォームを初めて使用する場合は、「リソース」にあるポイント & クリック開発に関する記事を参照することを強くお勧めします。
コーディングが好きな .NET 開発者の皆さんは、Lightning プラットフォームではコードが必要とは限らないと認識しておく必要があります。重要なのは、コードが必要な状況とそうでない状況を理解することです。ポイント & クリックで開発するときと、コーディングが必要なときの違いについての詳細は、こちらの記事を参照してください。
ポイント & クリックの話はこれくらいにして、このプラットフォームでのプログラミング方法、つまり Apex を使用する方法について学習していきましょう。
類似点
Apex プログラミング言語は、皆さんにはおそらくお馴染みの C# に似ています。Apex は、Lightning プラットフォーム上で直接に保存、コンパイル、および実行されます。C# と同様、オブジェクト指向です。このセクションでは、このような .NET 言語との類似点について説明します。
オブジェクト指向設計
皆さんはすでにオブジェクト指向設計の概念を把握していると思われますので、同じ話を繰り返して時間を無駄にするのはやめましょう。Apex では、カプセル化、抽象化、継承から多態性まで、オブジェクト指向の原則の多くがサポートされていることだけを覚えておいてください。実際に、Apex 言語には、クラス、インターフェース、プロパティ、コレクションなど、すでに使い慣れている多くの言語構造が含まれています。
たとえば、次のような HelloWorld という Apex クラスがあります。
public with sharing class HelloWorld { public void printMessage() { String msg = 'Hello World'; System.debug(msg); } }
この単純な HelloWorld クラスには、システムデバッグログにメッセージ「Hello World」を出力するためだけに使用される printMessage というメソッドが 1 つ含まれています。かなり単純な例ですので、Apex が C# とよく似ていることを確認しやすいでしょう。
クラスを定義するための基本構文は、次のようになります。
private | public | global [virtual | abstract] [with sharing | without sharing | inherited sharing] class ClassName [implements InterfaceNameList] [extends ClassName] { // The body of the class }
時間があれば、「クラスを理解する」を参照してクラス、オブジェクト、およびインターフェースのしくみについて詳細を学習してください。
データ型
Apex では、通常求められるデータ型はサポートされています。Integer、Double、Long、Date、Datetime、String、Boolean などのプリミティブ型があります。システムで割り当てられる有効な 18 桁の Lightning プラットフォームレコード識別子に使用される ID データ型もあります。
値と参照のデータ型は同様に機能しますが、Apex ではすべての変数がデフォルトで null に初期化されます。注意点の 1 つは、.NET 文字列は不変であるため、値の型のように動作しても実際には参照になることです。一方、Apex では文字列は常にプリミティブな値の型として扱われます。
プリミティブ以外にサポートされるデータ型として sObject があり、汎用 sObject か、取引先、取引先責任者など特定の sObject になります。sObject は単なる Salesforce オブジェクトです。これはデータベースのテーブルのようなものと考えることができます。sObject には、Salesforce に組み込まれている標準 sObject と自分で定義するカスタム sObject があります。
さらに、データ型を Enum (列挙) とも呼ばれる型付けされた値のリストにできます。ただし、これらは .NET で使い慣れている Enum とは異なりますので注意してください。Apex では、数値を含む Enum を使用できますが、これらの数値の内容を定義することはできません。また、序数の割り当ては 0 から開始します。たとえば、次のような Enum があるとします。
public enum myEnums { Enum1, Enum2, Enum3 }
3 つ目の Enum の序数値にアクセスしようとする場合、enumOrd 変数の値は 2 になります。
Integer enumOrd = myEnums.Enum3.ordinal();
コレクションの使用
.NET では、多くの型と拡張メソッドを含む大規模な 1 つのコレクションライブラリがサポートされています。その点でよい知らせがあります。Apex には次の 3 つのコレクションしかありません。シンプルでしょう?
リスト
リストは、従来の配列と同様に動作する要素の順序付けされたコレクションです。ただし、Apex は配列をコレクションとしてではなく、リストとしてサポートします。それでも「配列表記」と呼ばれる機能により、角括弧 [ ] を使ってリスト内の特定の項目を参照できます。たとえば、次の方法で変数を文字列のリストとして宣言できます。
List<String> myStrings = new List<String>();
または、次のように、角括弧を使って myStrings リスト変数を宣言できます。
String[] myStrings = new List<String>();
他にも、次のような 1 ステップでリストを宣言してその値を初期化できます。
List<String> myStrings = new List<String> {'String1', 'String2', 'String3' };
また、次のようにリストを作成した後に値を追加することもできます。
List<String> myStrings = new List<String>(); myStrings.add('String1'); myStrings.add('String2'); myStrings.add('String3');
すべての SOQL クエリの出力はリストであるため、Apex 開発では多くのリスト変数を作成することになるでしょう。たとえば、次のようなコードを使用して取引先のリストを作成できます。
List<Account> myAccounts = [SELECT Id, Name FROM Account];
リストのインデックスは、常に 0 から始まります。そのため、リストの最初の取引先の名前にアクセスする場合は、次のようになります。
String firstAccount = myAccounts.get(0).Name;
また、次の方法でも同様にアクセスできます。
String firstAccount = myAccounts[0].Name; // Uses Array Notation []
セット
セットは、重複を含まない要素の順序付けされていないコレクションです。セットは通常、ID 値の保存に使用されます。ID の値は常に一意であるためです。そのため、セットを SOQL クエリの WHERE 句の一部として使用できます。たとえば、取引先の一意の ID が 2 つ含まれるセットを次のように作成できます。次にこのセットを SOQL クエリで使用して、それらの ID に対する取引先のみを返します。
Set<ID> accountIds = new Set<ID>{'001d000000BOaHSAA1','001d000000BOaHTAA1'}; List<Account> accounts = [SELECT Name FROM Account WHERE Id IN :accountIds];
対応付け
対応付けは、キー - 値のペアのコレクションです。各キーは 1 つの値に対応付けられます。対応付けは、キーですばやく検索する必要がある場合に便利です。キー値は一意である必要があります。それにより、対応付けに含まれるキーの ID 値を sObject に対応付けることができます。たとえば、次のコードを使用してその ID に対応付けられたすべての取引先が含まれる、accountMap という対応付け変数を宣言できます。
Map<Id, Account> accountMap = new Map<Id, Account>([SELECT Id, Name FROM Account]);
次に、get メソッドと次のようなコードを使用して特定の取引先レコードにアクセスできます。
Id accId = '001d000000BOaHSAA1'; Account acc = accountMap.get(accId);
Apex がサポートするデータ型についての詳細は、公式なドキュメントを参照してください。
ASP.NET と Visualforce
ASP.NET Web フォーム開発者であれば、すぐに Visualforce に習熟できることでしょう。これら 2 つの間には多くの類似点があります。特に、どちらもコードとマークアップが明確に分離されています。また、フォーム項目は、コードをコントローラーに定義されているプロパティに対応付けるためにも使用します。
厄介な点としては、HTTP がステートレスであるため、ビューステートは Visualforce でも ASP.NET と同様に扱いづらいことです。幸い、ビューステートの制限を回避する方法があります。詳細は、「リソース」のリンクを参照してください。
Visualforce は、MVC パラダイムを使用して HTML ページを表示するためのフレームワークです。「Visualforce は、大好きな ASP.NET MVC と似ている」と大喜びするのはまだ待ってください。この 2 つを比較することはりんごとかぼちゃを比較するようなものです。どちらを使用しても Web ページを表示でき、どちらもアプリケーションロジックをマークアップとデータベースモデルから分離できますが、その方法が異なります。
Visualforce についての詳細は、「Visualforce の基本」モジュールを参照してください。ここでは、例を挙げながら Visualforce のしくみについて基本的な考え方のみを説明します。次のマークアップコードを使用して、取引先責任者データの入力に使用する単純なページを表示できます。
<apex:page standardController="Contact"> <apex:form> <apex:pageBlock title="Edit Contact" mode="Edit"> <apex:pageBlockButtons > <apex:commandButton action="{!edit}" id="editButton" value="Edit"/> <apex:commandButton action="{!save}" id="saveButton" value="Save"/> <apex:commandButton action="{!cancel}" id="cancelButton" value="Cancel"/> </apex:pageBlockButtons> <apex:pageBlockSection > <apex:inputField value="{!contact.lastname}" /> <apex:inputField value="{!contact.accountId}"/> <apex:inputField value="{!contact.phone}"/> </apex:pageBlockSection> </apex:pageBlock> </apex:form> </apex:page>
この例では、Lightning プラットフォームに含まれている標準コントローラーと呼ばれる機能を使用しています。これは基本的にはシステムで生成されるコードであり、Visualforce ページに基本の CRUD 機能をすばやく取り込めるようにします。より複雑なコードを追加する場合は、独自のカスタムコントローラーを作成できるので安心してください。標準コントローラーとカスタムコントローラーのしくみについての詳細は、「Visualforce の基本」モジュールを参照してください。このページは、次のように表示されます。
相違点
Apex と .NET との類似点について少し理解できたので、次は相違点を確認しましょう。まず、C# とは異なり、Apex は大文字と小文字を区別しません。
Apex とデータベースは緊密に結合されている
Apex コードと Lightning プラットフォームデータベースは緊密に結合されているため、区別できない場合もあります。データベース内の標準オブジェクトとカスタムオブジェクトにはそれぞれ、データベースとのやり取りを簡単にするためのあらゆる機能を提供する、Apex クラスを介した「謎の」表現があります。本質的に、クラスとその基礎となるオブジェクトは常に同期される互いのミラーイメージです。たとえば、オブジェクトに新しい項目を作成すると常に、クラスメンバーが自動的に表れてデータベースの値を参照します。存在しない項目への参照を Apex コードに追加することもできません。コンパイラーでエラーが返され、コードが保存されません。プラットフォームは、こうした連動関係を維持し、データベーススキーマとコード間の同期が途切れないように機能します。そのため、Apex コードで参照されるカスタムオブジェクトや項目を削除しようとすると、プラットフォームでエラーが発生し、そのアクションは許可されません。
設計パターンが異なる
.NET 開発者であれば、おそらくすでに設計パターンに習熟しているでしょう。ただし、そうしたパターンのほとんどは Lightning プラットフォームでは機能しません。これについては、次の単元で実行コンテキストとトリガーの設計を取り上げる際に説明しますが、「リソース」にある Apex 設計パターンに関するリンクも確認することをお勧めします。
重要なのは、.NET で使用するのと同じ設計戦略を Lightning プラットフォームに適用しようとすると、ソリューションをテストおよびリリースするときに問題が発生する可能性があると理解しておくことです。コーディングを開始する前に、少し時間を取って Lightning プラットフォーム環境で最適に機能する設計パターンについて学習することをお勧めします。
単体テストは必須である
.NET アプリケーションの単体テスト記述に慣れている方なら、単体テストを使用する利点についても理解されているはずです。Lightning プラットフォームでは、Apex コードを本番組織にリリースするには 75% のテストカバー率が必要である点が異なります。
単体テストの実施により、各メジャーリリースの前にはすべてのテストが実行されるため、単体テストは堅牢かつエラーのないコードの開発を促進するだけでなく、プラットフォームの安定性にとっても不可欠です。単体テストについての詳細は、「An Introduction to Apex Code Test Methods (Apex コードテスト方法の概要)」を参照してください。
ソリューションファイル、プロジェクトファイル、設定ファイルがない
Lightning プラットフォームには、ソリューションファイルやプロジェクトファイルのようなものがありません。アプリケーションを作成できますが、それは .NET アプリケーションまたはアセンブリの作成と同じではありません。
Lightning プラットフォーム上のアプリケーションは、タブ、レポート、ダッシュボード、ページなどのコンポーネントの緩いコレクションにすぎません。Salesforce 組織に標準で組み込まれているものもありますが、ポイント & クリック操作のウィザードに従って独自のアプリケーションをまたたく間に作成することもできます。サードパーティが開発したアプリケーションを AppExchange で購入することもできます。
コードはすべてクラウドで保存され、実行されます。Lightning プラットフォーム環境には設定ファイルのようなものもありません。データベースは直接組み込まれているため、接続文字列は必要ありません。さらに ASP.NET MVC とは異なり、ルートを設定する必要がありません。Salesforce にカスタム設定を作成できますが、これらは宣言的に追加および管理されます。
クラスライブラリがはるかに小さい
Apex クラスライブラリは .NET Framework クラスライブラリよりはるかに小さいため、容易かつ迅速に Apex を高速化することができます。正直なところ、Apex で比較できる機能を探そうとして存在しないことがわかり、がっかりするかもしれません。
Lightning プラットフォームは、迅速なアプリケーション開発を提供するという考えに基づいて構築されていることに留意してください。この点も .NET プラットフォームとは異なるため、使い慣れた機能を探しているのに結局 Lightning プラットフォームに存在しないということもあり得ます。ただし、詳細かつ完璧にカスタムコーディングされたアプリケーションを開発する方法を検討している場合は、Heroku Enterprise プラットフォームによって必要な性能と機能を得られます。
開発ツール
皆さんの多くはすでに無料の Developer Edition (DE) 組織にサインアップされていて、おそらくオンラインの開発者コンソールアプリケーションも開いて使用したことがあると思います。
開発者コンソールは、ソースコードの編集や操作に使用できます。また、デバッグやトラブルシューティングにも役立ちます。これについては後の単元で説明しますので、このまま続けましょう。データベースの基本に関する最初のモジュールを修了している場合は、開発者コンソールを SOQL および SOSL クエリの実行とクエリプランの表示にも使用できることをご存じでしょう。これまで開発者コンソールを使用したことがなくても、Apex クラスを作成するときに簡単に説明しますので心配はいりません。
.NET 開発者の方は、おそらくもう Visusal Studio コードのことは熟知されていると思います。実はローカルマシンでカスタム開発を行うことができる VS Code 向け Salesforce 拡張機能が用意されているのです。この拡張機能は、最新のソース駆動型開発体験を提供する Salesforce DX と密接に結び付いています。Salesforce DX の詳細は「Salesforce DX 入門」トレイルを参照してください。
さらに、Lightning プラットフォームへの強力なコマンドラインインターフェースもあります。コマンドラインを好む開発者は、Salesforce CLI を使用できます。
Salesforce の DevOps 向け評価および標準サポートの最新情報は、コードビルダーと DevOps Center をご確認ください。
セキュリティの処理
Lightning プラットフォームでは、認証や、パスワードおよびデータベース接続文字列の保存について心配する必要がありません。ID はプラットフォームによって処理されます。データへのアクセスは、オブジェクトレベル、レコードレベル、項目レベルなど、多様なレベルでコントロールできます。セキュリティも宣言的に処理されます。多くの場合、セキュリティは Salesforce システム管理者によって定義および設定されます。開発者にとって、そのしくみを意識しておくことが重要です。詳細は、「データセキュリティ」モジュールを参照してください。
インテグレーションについて
Force.com プラットフォームとのインテグレーションにはさまざまな方法がありますが、SOAP と REST を最もよく使用することになるでしょう。これらはどちらの方向にも使用できます。
Apex プログラミング言語を使用して Web サービスを作成して公開したり、Apex から外部 Web サービスを呼び出したりできます。受信したメールメッセージに対応し、特定のイベントが発生したら送信メッセージを自動送信することもできます。
自分で処理を開発する場合は、Salesforce が提供する SOAP API と REST API を使用して組織のデータに直接アクセスできます。API をラップするツールキットを使用できるため、.NET、Java、PHP、Objective C、Ruby、JavaScript のどれでも好きな言語を使用できます。
AppExchange では多くのサードパーティインテグレーションアプリケーションも入手できます。つまり、ほぼどのような処理でも可能です。すべてのインテグレーションポイントについての詳細は、「Apex インテグレーション」モジュールを参照してください。
Apex クラスを作成する
Lightning プラットフォームと .NET プラットフォームの関連について理解が深まったところで、早速開発者コンソールを使用して Apex クラスを作成してみましょう。作成するクラスには公開メソッド sendMail が含まれます。このメソッドには、メール送信コールの結果を検査する inspectResults という非公開ヘルパーメソッドが含まれます。
- 開発者組織の [設定] で、[<あなたの名前>]あなたの名前> > [開発者コンソール] をクリックして開発者コンソールを開きます。
- 開発者コンソールで、[File (ファイル)] > [New (新規)] > [Apex Class (Apex クラス)] を選択します。
- クラス名を「EmailManager」と指定し、[OK] をクリックします。
- 既存のコードを削除して、次のスニペットを挿入します。
public with sharing class EmailManager { // Public method public static void sendMail(String address, String subject, String body) { // Create an email message object Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); String[] toAddresses = new String[] {address}; mail.setToAddresses(toAddresses); mail.setSubject(subject); mail.setPlainTextBody(body); // Pass this email message to the built-in sendEmail method // of the Messaging class Messaging.SendEmailResult[] results = Messaging.sendEmail( new Messaging.SingleEmailMessage[] { mail }); // Call a helper method to inspect the returned results. inspectResults(results); } // Helper method private static Boolean inspectResults(Messaging.SendEmailResult[] results) { Boolean sendResult = true; // sendEmail returns an array of result objects. // Iterate through the list to inspect results. // In this class, the methods send only one email, // so we should have only one result. for (Messaging.SendEmailResult res : results) { if (res.isSuccess()) { System.debug('Email sent successfully'); } else { sendResult = false; System.debug('The following errors occurred: ' + res.getErrors()); } } return sendResult; } }
-
Ctrl + S キーを押してクラスを保存します。
メソッドを呼び出す
公開 sendMail メソッドは静的として宣言したので、クラスのインスタンスを作成せずにアクセスできます。これは、開発者コンソールの匿名 Apex を使用して簡単に行うことができます。
- [設定] で、[<あなたの名前>]あなたの名前> > [開発者コンソール] をクリックして開発者コンソールを開きます。
-
[Debug (デバッグ)] > [Open Execute Anonymous Window (実行匿名ウィンドウを開く)] を選択します。
- 既存のコードを削除して、次のスニペットを挿入します。
EmailManager.sendMail('Your email address', 'Trailhead Tutorial', '123 body');
- [Open Log (ログを開く)] オプションが選択されていることを確認し、[Execute (実行)] をクリックします。新しいタブに実行ログが表示されます。
- ログにデバッグステートメントのみが表示されるように、[Debug Only (デバッグのみ)] オプションを選択します。メールが正常に送信されたことを伝えるメッセージが表示されます。有効なメールアドレスを入力していれば、メールも受信します。
同じ作業を .NET で行うことを想像してみてください。メールを送信する .NET アプリケーションの作成はこのように簡単でしょうか? 正直に答えましょう。
リソース
-
Salesforce アーキテクチャについて
-
Visual Development – When to Click Instead of Write Code (ビジュアル開発 – コードを書くのではなくクリック操作で開発するのはどのような場合か)
- 『Apex コード開発者ガイド』の「Apex の概要」
-
An Introduction to View State (ビューステートの概要)
-
Apex Design Patterns (Apex 設計パターン)
-
インテグレーションのパターンと実践