Web Developer Specializationは2023/3に追加された試験で、ReactiveのProfessional認定の条件の1つ。
試験情報のPDFと一緒にダウンロードできるサンプル問題を解説する。
全部で10問で、この記事では1問目-5問目が対象。
Web Developer Specializationのサンプル問題について解説 2/2(#6-#10)
サンプル問題は、
https://www.outsystems.com/learn/certifications/
の、「Web Developer Specialist」項目のリンク「Exam Details」でダウンロードできる資料から。「Sample Exam」がついている方のファイルが該当する。
この記事では、zipを展開したときに、ファイルの更新日時が2023/04/05 9:15のものを使って各問題を見ていく。
残念ながら、2023/04/08時点では英語のみ。
Professional Web/Mobile Developer Certification
今回公開された試験で、Reactive Web Appでも、Professionalレベルの認定を受けられるようになった。
条件は、
- Associate Reactive Developer
- Security Specialization
- Web Developer Specialization
- Architecture Specialization
の各試験を合格すること。
上記に加えて
- Mobile Dev Specialization
も合格すると、Professional Mobile Developer Certificationを受けられる。
Web Developer SpecializationのAnnouncementに体系図が載っているので、参考までに。
1 長時間実行されるTimerのベストプラクティス
問題文の検討
たくさんのデータを外部システムに同期するTimerのロジックで、ベストプラクティスに従っていない部分を指摘するもの。
Action Flowを見ると、Entityで取得したレコードをFor Eachでループ。
各ループで、
- Action(おそらく外部システムにアクセス)を呼ぶ
- Entity Actionでレコードを作成
- CommitTransaction Actionでコミット実施
をしている。
これを見ると気付くのは、
- OutSystemsのベストプラクティスタイマーおよびバッチジョブの長期-実行を避けるに違反している(なぜか日本語ページにリンクできなかったので英語のページ)
- 1レコードごとにCommitTransaction発行するのは頻度が高い
選択肢の検討
A. ×:問題は明らかにある
B. ×:Timeout in Minutesは20分程度にするのがベストプラクティスなのでスクリーンショットにある20より大きい値にするのは推奨されない。同じサーバーのリソースを食いつぶさないためTimerの同時実行数には制限がある(デフォルトではPlatform Serverあたり3)ため
C. ×:CommitTransactionが多いのは事実だが、それがだめかどうかは、各ループで呼んでいる外部処理による。少なくともTimerの最後にループの外でCommitするのはベストプラクティスで推奨されている事項ではない。コミットは、ループ中にIfを置いて一定の回数や経過時間等で行うのがよい。Timerの最後に到達するとOutSystemsが自動的にコミットを行うためその位置で明示的にCommitTransactionを行うのは意味があるとは言えない
D. 〇:これがベストプラクティスに従った実装。こうした実装の例はAsynchronous Processing with Timers - Best Practices on Timersで紹介されている
2 Consume REST APIのInput Parameter
問題文の検討
Consume REST APIエラーに渡すInput Parameter "Phone Number"がある。
実行時に“The PhoneNumber attribute must not be null”というエラーが発生するのでこれを解決する方法を聞かれている。
スクリーンショットを見ると、PhoneNumber項目のSend Default Value=Noが設定されている。この設定をすると、該当Parameterがデフォルト値の場合、「項目自体を省略する」。エラーメッセージと併せて考えると、PhoneNumberが空白の値であるために、API呼び出し時に項目自体を渡さなかったために発生したエラーと思われる。
他の条件として
- 対象APIは他のInput Parameterを正しく受け取っている -> ネットワークや対象API自体には問題が起きていない
- PhoneNumber自体はmandatoryではない -> PhoneNumberを必須にするのは望ましくない
選択肢の検討
A. ×:PhoneNumberのDefault Valueをどんな値にしようとも、たまたまその値が設定された場合、実行時に項目が省略され、同じ問題が発生する。また未指定時に適切なPhoneNumberのデフォルト値があるという情報が与えられていない
B. 〇:これが正解。Send Default Value=Yesにしておけば、未指定の項目も省略されなくなる
C. ×:OnBeforeRequestはConsume REST APIのCallbackで、外部APIを呼ぶ直前に割り込んでHTTP通信の内容を書き換えることができる。よって選択肢に書いた通りのことは実現可能だが、選択肢Bの方が明らかに自然で簡単な方法なので、Bがある以上はこの選択肢は×
D. ×:問題文の検討で見た通りMandatoryにするのは望ましくない
3 Merge
問題文の検討
Publishを行ったときにCompare and Mergeダイアログが表示され、conflictの存在が示されている(背景色が赤い部分)。conflictがある行でどちらも選択しないままMerge and Publishボタンをクリックした。
conflictが残ったままなのでService Studioは自動でマージを行えない。そのため、選択肢Dが正解。
4 Exception HandlerとTransaction
問題文の検討
- Consume REST API呼び出し
- "UpdateCustomerDB"という名前のAction (名前からしてEntityの更新があるのだろう)呼び出し
で構成されるActionがある。1を終えて、2でエラーが起きて、Exception Handlerに捕捉された。なお、Exception HandlerのAbort Transaction=Yesになっているため、補足された時点でトランザクションはロールバックされる。
選択肢の検討
この問題の状況では、2.のUpdateCustomerDBはロールバックされるが、1.のConsume REST API呼び出し先のトランザクションはロールバックされない。外部サービスはOutSystemsのトランザクション管理から独立しているため。
各選択肢は以下の通り
A. 1, 2共にロールバックされる
B. 1, 2共にコミットされる
C. 1はロールバックされず、2はロールバックされる
D. 1はロールバックされ、2はコミットされる
↑の説明に合うのは、選択肢C。
5 大きいテキストデータやバイナリデータを分離する
問題文の検討
あるEntityにDescriptionという属性がある。この属性のデータ型はTextで桁数が2000を超える。
この状況はベストプラクティスにある大きいテキストデータやバイナリデータを分離するに該当する。日本語のページへのリンクはなぜか機能しないため英語のページへのリンク。
ポイントは
- Binary Data型の属性を含むEntityは更新に時間がかかるため、Binary Data型を分離して別のEntityに切り出す
- このEntityは元のEntityのIdentifierを自分のIdとして持つ(元のEntityと分離したEntityは1:1の関係にある)
- 長さが2000を超えるText型属性も背後のRDB内ではBinaryのデータとして扱われるため同じ注意が必要
選択肢の検討
上記ベストプラクティスから、元のEntityと1:1の関係にある新しいEntityを作り、Description属性はそちらに移動することになる。
よって、選択肢Bが正解。