革命のブログ

フレボワークスの社員がブログを通じて情報発信します。

React Nativeを選んだ理由とは?

どうも、小野です。私はずっとWebアプリ開発を行ってきたので、スマホアプリ開発は未経験です。興味本位で軽く触ったことはありますが、初心者同然です。最近、Android開発のデベロッパーに登録したこともあり、勉強し始めたところです。(iOSは1年単位の更新があるので登録していません) まず、スマホアプリ開発の方法として、以下の2つがあると思います。

  • Android、iOSそれぞれのネイティブ言語で開発する

  • クロスプラットフォームフレームワークを利用して開発する。

今回はネイティブ言語をそれぞれ学習するのは大変なので、後者について検討してみます。現在、クロスプラットフォームなフレームワークには主にReact NativeとFlutterが主流となっています。 React NativeとFlutterの比較は他の記事にもたくさんあるのでそちらを参考にしていただき、ここでは私がReact Nativeを選択した理由をお話したいと思います。(正確にはReact Native+Expoです。) 選択した理由としては3つあります。

  • TypeScriptで開発が可能

  • ストアを介さずにアップデートが可能

  • 開発OSに制限がない

TypeScriptで開発ができる

TypeScriptは現代のWebフロントエンド開発において最も人気のある言語の一つです。特に以下のような利点があります。

  • 静的型チェックによりバグの早期発見が可能

  • コード補完やリファクタリングのサポートが充実

  • 大規模なアプリケーション開発での保守性が高い

Webフロントエンド開発者にとって、React NativeでTypeScriptが使えることは以下のような大きなメリットがあります:

  • 既存のTypeScriptの知識やベストプラクティスをそのまま活用できる

  • React/React Nativeのコンポーネント開発で型の恩恵を受けられる

  • npmパッケージの型定義を活用でき、安全にライブラリを利用できる

これにより、Webフロントエンド開発からモバイルアプリ開発への移行がスムーズになり、学習コストを大幅に削減することができます。

※FlutterはDartという言語を覚える必要があります。

ストアを介さずにアップデートが可能

アプリをストアを介さずに更新できるOTAアップデート(Over The Air update)が可能です。 React NativeとExpoを組み合わせることで、アプリの新バージョンをサーバーにアップロードし、ユーザーが次回アプリを起動した際に自動的に更新を適用することができます。 これにより、以下のようなメリットがあります。

  • バグ修正や小規模な機能更新を迅速にリリースできる

  • App StoreやGoogle Play Storeのレビュープロセスを待つ必要がない

  • ユーザーが手動でアプリを更新する手間を省ける

ただし、ネイティブコードの変更を伴う更新の場合は、従来通りストアを通じた配布が必要になります。

※Flutterにはこのような機能はありません。

開発OSに制限がない

通常、iOSアプリを開発する場合、ビルドやテストにMacOSが必要となります。これは、iOSの開発環境であるXcodeがMacOS専用のソフトウェアだからです。 しかし、React NativeとExpoを組み合わせ、さらにEAS(Expo Application Services)を利用することで、この制限を回避できます。EASはクラウド上でビルドを実行するため、開発者のローカル環境に依存せず、WindowsやLinuxなど、どのOSからでもiOSアプリの開発が可能になります。 これにより、以下のようなメリットがあります。

  • 開発チームのメンバーが好みのOSを選択できる

  • MacOSの端末を用意する必要がなく、初期コストを抑えられる

  • クラウド上でビルドを行うため、ローカル環境の負荷を軽減できる

※Flutterを利用した場合、iOSアプリ開発にはMacOSが必要になります。

注意点

React Native + Expoには以下のようなデメリットがあるので、それを理解した上でプロジェクトの要件に合わせて適切な判断を行うことが重要です。

  • ネイティブな機能へのアクセスが制限される可能性がある

  • バンドルサイズが大きくなりがち

  • パフォーマンスがネイティブアプリに比べて劣る場合がある

Expoの無料プランには制限がある(ビルド回数制限など) 特に以下の場合は、React Native + Expoの使用を慎重に検討する必要があります。

  • 高度なハードウェア機能を使用する必要がある場合

  • 極めて高いパフォーマンスが要求される場合

  • アプリのサイズを極限まで小さくする必要がある場合

おわりに

注意点にも書きましたが、採用するかどうかはアプリ要件次第ではあるので、慎重に検討する必要があります。私自身、仕事で開発予定はなく、個人で開発する手始めとして調査したところ、学習コストをかけずにできることが最優先ではあったので、ReactNativeを採用しました。 もし、アプリ開発の方法で悩んでたら判断材料として参考にしていただけると幸いです。

AWS SAMとserverless-java-containerを使って、SpringBootアプリケーションを最速で構築してみた

はじめに

久しぶりの技術記事です。今回はタイトルにもあるとおりJavaのディファクトスタンダードでもあるフレームワークSpringBootのアプリケーションをAPI Gateway+Lambdaに構築する方法をご紹介します。

昔はLambdaのランタイムとしてJavaを利用することは、JVM起動時間が遅いため避けられてきましたが、「Lambda SnapStart」機能の追加により起動速度が向上し、実用的に利用できるようになりました。このアップデートによりアーキテクチャの選択肢としてJavaも実用的なものとなっています。

※今回はSnapStartの設定は行いません。

事前準備

  • AWSアカウントを持っていること
  • Administrator権限のIAMユーザが作成されていて、アクセスキー、シークレットキーを発行していること

環境

  • Windows11

手順

JDKのセットアップ

こちらのページよりインストーラーをダウンロードします。

ダウンロードが完了したらインストーラーを実行し、インストールを行います。

インストールが完了したら、コマンドプロンプトを起動し、以下のコマンドを実行します。

> java -version

openjdk version "21.0.5" 2024-10-15 LTS
OpenJDK Runtime Environment Corretto-21.0.5.11.1 (build 21.0.5+11-LTS)
OpenJDK 64-Bit Server VM Corretto-21.0.5.11.1 (build 21.0.5+11-LTS, mixed mode, sharing)

上記の結果が表示されればセットアップ完了です。

※JDKのディストリビューションをAmazon Correttoにしているのは、LambdaのJavaランタイムが使用しており、ローカルとの環境の差分をなくすためです。

Mavenのセットアップ

こちらのページよりバイナリをダウンロードします。

ダウンロードしたファイルを解凍し、C:\Program Filesに移動します。

環境変数Pathに C:\Program Files\apache-maven-3.9.9\bin 追加します。

コマンドプロンプトを起動し、以下のコマンドを実行する。

> mvn -v

Apache Maven 3.9.9 (8e8579a9e76f7d015ee5ec7bfcdc97d260186937)
Maven home: C:\Program Files\apache-maven-3.9.9
Java version: 21.0.5, vendor: Amazon.com Inc., runtime: C:\Program Files\Amazon Corretto\jdk21.0.5_11
Default locale: ja_JP, platform encoding: UTF-8
OS name: "windows 11", version: "10.0", arch: "amd64", family: "windows"

上記の結果が表示されればセットアップ完了です。

AWS CLIのセットアップ

こちらのページを参考にインストールを行います。

コマンドプロンプトを起動し、以下のコマンドを実行します。

> aws --version

aws-cli/2.22.34 Python/3.12.6 Windows/11 exe/AMD64

上記の結果が表示されればセットアップ完了です。

AWS SAMのCLIのセットアップ

こちらのページを参考にインストールを行います。

コマンドプロンプトを起動し、以下のコマンドを実行します。

> sam --version

SAM CLI, version 1.132.0

上記の結果が表示されればセットアップ完了です。

AWSプロファイル設定

コマンドプロンプトを起動し、以下のコマンドを実行します。

> aws configure

AWS Access Key ID [None]: XXXXXXXXXXXXXX
AWS Secret Access Key [None]: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
Default region name [None]: ap-northeast-1
Default output format [None]:

AWS Access KeyとAWS Secret Access KeyにIAMで作成したユーザのものを設定します。

プロジェクト作成

コマンドプロンプトを起動し、以下のコマンドを実行します。

> mkdir C:\workspace
> cd C:\workspace
> mvn archetype:generate -DgroupId=my.service -DartifactId=my-service -Dversion=1.0-SNAPSHOT -DarchetypeGroupId=com.amazonaws.serverless.archetypes -DarchetypeArtifactId=aws-serverless-springboot3-archetype -DarchetypeVersion=2.1.1

作成したプロジェクト内にあるbuild.gradleファイルを削除します。

デプロイ

コマンドプロンプトを起動し、以下のコマンドを実行します。

> sam build

Building codeuri: C:\workspace\my-service runtime: java21 architecture: x86_64 functions: MyServiceFunction
 Running JavaMavenWorkflow:CopySource
 Running JavaMavenWorkflow:MavenBuild
 Running JavaMavenWorkflow:MavenCopyDependency
 Running JavaMavenWorkflow:MavenCopyArtifacts

Build Succeeded

Built Artifacts  : .aws-sam\build
Built Template   : .aws-sam\build\template.yaml

Commands you can use next
=========================
[*] Validate SAM template: sam validate
[*] Invoke Function: sam local invoke
[*] Test Function in the Cloud: sam sync --stack-name {{stack-name}} --watch
[*] Deploy: sam deploy --guided

上記の結果が出力されれば、ビルド完了です。

次に以下のコマンドを実行し、デプロイします。

> sam deploy --guided

Configuring SAM deploy
======================

        Looking for config file [samconfig.toml] :  Not found

        Setting default arguments for 'sam deploy'
        =========================================
        Stack Name [sam-app]:
        AWS Region [ap-northeast-1]:
        #Shows you resources changes to be deployed and require a 'Y' to initiate deploy
        Confirm changes before deploy [y/N]: N
        #SAM needs permission to be able to create roles to connect to the resources in your template
        Allow SAM CLI IAM role creation [Y/n]: Y
        #Preserves the state of previously provisioned resources when an operation fails
        Disable rollback [y/N]: N
        MyServiceFunction has no authentication. Is this okay? [y/N]: y
        Save arguments to configuration file [Y/n]:
        SAM configuration file [samconfig.toml]:
        SAM configuration environment [default]:

以下の結果が出力されたらデプロイ完了です。

CloudFormation outputs from deployed stack
---------------------------------------------------------------------------------------------------------------------
Outputs
---------------------------------------------------------------------------------------------------------------------
Key                 MyServiceApi
Description         URL for application
Value               https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/ping
---------------------------------------------------------------------------------------------------------------------

Successfully created/updated stack - sam-app in ap-northeast-1

動作確認

コマンドプロンプトを起動し、以下のコマンドを実行します。

> curl https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/ping
{"pong":"Hello, World!"}

レスポンスが返ってくることを確認してください。

アプリケーション更新

src\main\java\my\service\controller\PingController.javaを以下のように変更します。

package my.service.controller;

import org.springframework.web.bind.annotation.*;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;

import java.util.HashMap;
import java.util.Map;

@RestController
@EnableWebMvc
public class PingController {
    @RequestMapping(path = "/ping", method = RequestMethod.GET)
    public Map<String, String> ping() {
        Map<String, String> pong = new HashMap<>();
        pong.put("pong", "Hello, Serverless!");// メッセージ変更
        return pong;
    }
}

保存したら、以下のコマンドを実行してください。

> sam build
> sam deploy

※sam deplyのオプション「guided」が不要なのは、1回目に実行した際に作成されたsamconfig.tomlに選択した内容が保存されており、2回目以降はこちらのファイルが参照されるためです。

デプロイが完了したら、以下のコマンドを実行し変更されたか確認してください。

> curl https://xxxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/Prod/ping

メッセージが変更されていれば更新成功です。

今回はソースの変更を行いましたが、template.yamlファイルでAWS環境の構築や変更を行うことも可能です。(RDS作成など)

最後に

今回作成したプロジェクトを土台として、開発を進めることが可能になりました。実際のアプリケーションではDBを利用することになると思います。今後、別のブログでアップしていきたいと思います。

参考記事

年末年始の休業のお知らせ

平素より、弊社には格別のご厚情を賜り厚くお礼申し上げます。
誠に勝手ながら、下記のとおり年末年始休業とさせていただきます。

■休業期間:2024年12月28日(土)~2025年1月5日(日)

休業期間中のご連絡については、6日(月)以降、順次ご対応させて頂きます。

ご迷惑おかけしますが、宜しくお願い申し上げます。

夏季休業のお知らせ

弊社は、夏季休業を勝手ながら、以下の通りとさせて頂きます。

休業期間中でのお問い合わせ等は、終了後、順次させて頂きますので、

ご迷惑をお掛けしますが、宜しくお願い申し上げます。

ー 記 ー

自:2024年8月13日(火)

至:2024年8月16日(金)

 

また、その他、土日祝際日はお休みとなります。

宜しくお願い申し上げます。

- 年末年始休業のお知らせ -

当社は、誠に勝手ながら、2023年12月30日(土)~2024年1月4日(木)まで、年末年始休業とさせていただきます。
ご不便をおかけしますが、何卒、ご理解頂きますようお願い致します。

来年も、皆様のご多幸を、お祈り申し上げます。

 

結局、JPAがいいという話

どうも、小野です。

今回は数あるORマッパーの中で個人的に、今までで一番使ってきたであろうJPA(Java Persistence API)の特徴、そしてメリット、デメリットについてご紹介します。 本記事ではJPAの詳しい使い方は説明しません。

JPAとは

Java標準技術の1つ(JSR338: Java Persistence API)です。

JPAは仕様、つまりインターフェースのみ定義されており、実装自体は「Hibernate」や「EclipseLink」などを利用することになります。 HibernateとEclipseLinkはJPAの仕様に従って実装はされていますが、それぞれ独自実装もあったりするので、どちらがいいかは公式リファレンスを参照したり、実際に使ってみることをお勧めします。

JPAの特徴

SQLを意識せずに、Javaオブジェクトでデータを操作することが可能です。もちろん、全てJavaオブジェクトで完結することはなく、SQLを書くことはあります。 JPAでDB操作する際にはいくつか方法があります。

  • SQL
  • JPQL
  • Criteria API

SQL

今まで使ってきたSQLです。これは説明する必要がありませんね。SQLは、Javaクラス内にも書けるし、外部ファイル(xml)にも書けるので、プロジェクトのルールに従って柔軟に対応が可能です。

JPQL

SQLに似ているJPA独自の言語です。 例えば、以下のようなSQLがあったとします。

SELECT u.id, u.name,u.email FROM user u

JPQLで表現するにはデータをマッピングするクラスが必要になります。

@Entity
public class User {
    private String id;
    private String name;
    private String email;
}

@Entityはマッピングする際に最低限必要です。 JPQLで表現すると以下のようになります。

SELECT u FROM User u

FROM句で指定されているのはテーブル名ではなく、クラス名になります。SELECT句にはクラス名のエイリアスを指定すると、全カラムを取得するようになります。もし取得する列を指定したい場合は、SQLの時と同じ形で指定します。

SELECT u.name FROM User u

別にSQLで書けるならJPQL覚える必要ないと思いますが、テーブル結合のマッピングなど実現が難しいことがあるため習得は必須です。

Criteria API

JavaプログラムでSQLを構築、実行するためのAPIです。

JPQL同様にCriteria APIを使って書いてみます。Userクラスはそのまま利用します。

// entityManagerは予めインスタンスを生成しておく必要がありますが、ここでは割愛します。
CriteriaBuilder builder = entityManager.getCriteriaBuilder();
CriteriaQuery<User> query = builder.createQuery(User.class);
Root<User> root = query.from(User.class);
List<User> users = entityManager.createQuery(query.select(root)).getResultList();

Criteria APIのメリットはタイプセーフであることです。SQL、JPQLはタイプミスしていてもコンパイルエラーにはなりませんが、Criteria APIの場合、実装時にエラーを検知することが可能です。 あとは、動的SQLを書く際に利用することが多いです。MybatisのようにSQL内に制御構文を書けないので、SQLやJPQLで書く際はプログラム内で文字列結合や制御構文を駆使する必要が出てきます。

メリット

実装の削減

SQLやマッピングの実装を極力なくすことにより、生産性向上やバグを減らすことが期待できます。 INSERT、UPADTE、DELETEはほぼ書く必要がなく、EntityManagerとエンティティクラスでの操作が可能です。

INSERT

User user = new User();
user.setId("1");
user.setName("太郎")
user.setEmail("taro@abc.com");

entityManager.persist(user);

UPADTE

User user = entityManager.find(User.class, "1");
user.setName("次郎")
user.setEmail("jiro@abc.com");

DELETE

User user = entityManager.find(User.class, "1");
entityManager.remove(user);

※前提としてトランザクション内での操作になります。

デメリット

複雑なSQLへの対応

複雑なSQLを書く場合にひと手間が必要になることがあります。 JPQLやCriteria APIで書こうとすると、実現が難しいかできても可読性が悪いコードになってしまいがちです。そのため、チューニングが必要なものは生のSQLで書く必要があります。 ただし、生のSQLの場合、N対1や1対Nなどのテーブル結合のマッピングができないので、自分でマッピング処理を実装することになります。

実装の流れとしては、 SQLの実行結果を保持するクラスを用意し、データ取得後、各テーブルに対応したクラスへマッピングを行います。

実行SQLがブラックボックス

特にJPQLやCriteria APIを利用する場合、頭の中でこんなSQLが実行されるだろうなと思っていても実際は全く違うSQLが実行されていることも少なくありません。想定外のSQL実行を回避するために開発時は実行されたSQLをログに出力するようにしてください。上記でも触れた1対Nのテーブル結合のあるクエリを実行した際に、N+1問題にぶつかることがあります。それによりシステムのパフォーマンスが落ちたり、最悪の場合停止することも考えられます。

N+1問題については、以下のサイトを参考にしてください。

qiita.com

さいごに

JPAは学習コストが高いと言われています。実際使ってみた私からみてもやはりそのように感じます。それも当然です。書き方が3つもあり、実際に実行されるSQLを意識してないと痛い目見ますので。正直、CriteriaAPIだけ覚えればJPQLは覚えなくても問題ありません。基本的にJPQLにできてCriteriaAPIにできないことはないです。

個人的には3パターンの実装手段があることで、ケースに応じて使い分けることができるのがメリットかなと思います。

この記事が選定時のネタとして参考になれば幸いです。

ビデオ会議の記録に『tl;dv』を使ってみた

どうも、小野です。

最近、ビデオ会議に使える便利なツールを見つけたので紹介します。

そのツールは『tl;dv』というものです。以下、公式サイトです。

tldv.io

簡単に説明すると以下のような特徴があります。

  • GoogleMeet、Zoomによるビデオ会議の録画ができる。録画した動画の再生も可能
  • 作成された動画に対して、主要トピックを抜き出し時間指定リンクを自動作成。
  • 全ての発言内容を発言者ごとにテキストとして記録
  • 完全無料で利用可能

上記にもある通り、現在はGoogleMeetとZOOMにしか対応していないので、Teamsなど他のアプリで利用できません。

実際に画像を見せた方がどのくらい便利なのかわかると思います。

※実際に仕事で録画したものなので、中身はぼかしてます。

トップ画面

動画を選択後の画面

次に利用手順を説明してきます。(今回はGoogle Meetを前提にしています)

(1)tl;dvのサイトでサインアップを行ってください。

(2)以下のChrome拡張機能をインストールします。 chrome.google.com

(3)Google Meetを開始し、録画を開始します。

(4)録画を終了し、Google Meetを終了します。

準備から録画するまでの手順は以上になります。

今回は情報漏洩等を避けるためにぼかし箇所が多くわかりづらかったかもしれません。 無料で利用可能なので試しに使ってみてください。