※当サイトの記事には、広告・プロモーションが含まれます。

PostgRESTの使い道が分からんけど、JavaからAPIを呼び出してみる

news.yahoo.co.jp

⇧ 何て言うか、人手不足と言う割に日本人のIT人材の待遇を改善しようという思考は無いんだね...

学習のモチベーションだだ下がりですわ...

PostgRESTって?

PostgRESTについて、公式のドキュメントでは、

github.com

PostgREST serves a fully RESTful API from any existing PostgreSQL database. It provides a cleaner, more standards-compliant, faster API than you are likely to write from scratch.

https://github.com/PostgREST/postgrest

APIサーバーらしい。

何やら、

postgrest.org

Database as Single Source of Truth

Using PostgREST is an alternative to manual CRUD programming. Custom API servers suffer problems. Writing business logic often duplicates, ignores or hobbles database structure. Object-relational mapping is a leaky abstraction leading to slow imperative code. The PostgREST philosophy establishes a single declarative source of truth: the data itself.

https://postgrest.org/en/stable/

⇧ ORM(Object-relational mapping)のアンチテーゼみたいな感じなんかな、兎に角、ORMはイケてないじゃないか、だから用意しました、のようです。

とは言え、レスポンスがJSONっぽいので、レスポンスの値を処理するのにオブジェクトにパースする必要はありそうですかね。

アーキテクチャとしては、

postgrest.org

PostgREST is a standalone web server which turns a PostgreSQL database into a RESTful API. It serves an API that is customized based on the structure of the underlying database.

https://postgrest.org/en/stable/tutorials/tut0.html

⇧ 上図のような感じで、PostgRESTを仮想マシンないし、コンテナなどにインストールしておく必要があるっぽい。

勿論、WindowsとかMacにもインストールできるんだけども、本番環境ってなってくるとLinuxになると思うのだけど、なにがしかのマシンにインストールしておく必要があるらしい。

要するに、PostgRESTに向かってリクエストを投げると、PostgreSQL に対してCRUDしてくれるってことかね。

ドキュメントを見た限りでは、HTTPリクエストでの利用という形になるってことかと。

gRPCとかに対応してるのかは、分からんです...

PostgRESTの使い道が分からんけど、PostgRESTを導入するには

とりあえず、必要なものとしては、

の2つが最低限あれば良さそうではありますと。

ドキュメントを見た限りでも、

postgrest.org

PostgreSQL dependency

To use PostgREST you will need an underlying database. We require PostgreSQL 9.6 or greater. You can use something like Amazon RDS but installing your own locally is cheaper and more convenient for development. You can also run PostgreSQL in a docker container.

https://postgrest.org/en/stable/explanations/install.html#install

⇧ 上記以外には、特に必要なものとして記載は無さそう。

何はともあれ、PostgreSQL が無いと始まらないので、PostgreSQLを使える環境を用意しておきましょう。

自分は、

ts0818.hatenablog.com

⇧ 上記の記事の時に、「WSL 2(Windows SubSystem for Linux 2)」のUbuntuにインストールしていたPostgreSQLを利用します。

JavaでHTTPリクエストするライブラリ、どれ使えば良いの?

今回は、JavaからPostgRESTを利用するということにしたので、

PostgRESTが稼働できたら、PostgRESTに対して、JSONを送信するHTTPリクエストを実行する実装をJavaでする必要があるのだけど、

qiita.com

www.twilio.com

reflectoring.io

⇧ 上記サイト様によりますと、

  • Java標準のAPI
    • HttpURLConnection
    • HttpClient
      Java 11以上
  • Java標準ではないAPI
    • ApacheHttpClient
    • OkHttp
    • Retrofit
    • Spring Framework
      • RestTemplate
        Spring Web MVC に同梱
      • WebClient
        Spring WebFlux に同梱

の選択肢があるそうな。

ややこしいのは、

news.mynavi.jp

なお、WebClientはSpring WebFluxに内包された機能ではありますが、Spring MVCと組み合わせて使用することも可能です。Spring MVCでは「RestTemplate」というHTTPクライアントを提供していますが、RestTemplateはSpring Framework 5.0でメンテナンスモードとなり、今後はWebClientを使用することを推奨しています。

マイクロサービス時代に活きるフレームワーク Spring WebFlux入門(3) リアクティブなHTTPクライアント! WebClient入門 | TECH+(テックプラス)

⇧ とのこと。

2023年8月11日(金)時点で、

github.com

Spring Frameworkのバージョンは、6.0.11がリリースされているようなので、新規開発で、Java且つ、フレームワークSpring Framework を利用する場合は、「RestTemplate」の利用は避けた方が無難そうなんですかね。

Androidの知見が無いので何とも言えないですが、Webの開発でJava 11以上が利用できる環境である場合、どのHttpクライエントを利用するのが良いのだろうか?

Java標準のAPIであるHttpClient を利用してみる

せっかくなので、Java 11からJava標準のAPIに追加されたという「HttpClient」を利用する感じにしました。

qiita.com

⇧ 上記サイト様を参考にさせていただきました。

実際に利用されているのかは分からんのだけど、Java標準のAPIとして導入されたのだから、全く役に立たないことは無いと信じたい...

Java 11未満を利用しているようなレガシーなシステムでは、そもそも「HttpClient」は利用できないのですが...

プロジェクトは、

ts0818.hatenablog.com

⇧ 上記の記事の時のものに、「HttpClient」を実施する機能を追加していきます。

とりあえず、

github.com

Javaソースコード部分はGitHubに上げました。今回追加したのは、PostgRESTへのGETリクエストの実装だけですが...。

PostgRESTの使い道が分からんけど、JavaからAPIを呼び出してみる

まぁ、いまいち、PostgRESTの使いどころが全く分かっていないのですが、「Rancher Desktop」で、「PostgREST」を含んだDockerコンテナを用意することにします。

「WSL 2(Windows SubSystem for Linux 2)」環境だけなのかも知らんけど、

ts0818.hatenablog.com

⇧「PostgREST」を含んだDockerコンテナを起動する際に、Dcokerコンテナの「/etc/hosts」「/etc/resolv.conf」へ設定を追加するように注意が必要ですかね。

一応、

hub.docker.com

PostgREST serves a fully RESTful API from any existing PostgreSQL database. It provides a cleaner, more standards-compliant, faster API than you are likely to write from scratch.

https://hub.docker.com/r/postgrest/postgrest/

⇧ Docker Hubで公式のDokcerイメージが用意されてる模様。

公式のイメージなので、

news.mynavi.jp

⇧ のような心配は無いと思うけど...

それでは、Dockerが利用できるように「Rancher Desktop」を起動。Docker使えるのであれば、「Rancher Desktop」でなくても問題ないです。

⇧ 今日はエラーが出ていない、エラー出たり出なかったり、「Rancher Desktop」よく分からんな...


⇧ 警告は相変わらず出てるけど。

Dockerが使える準備が整ったら、Dcoker HubからPostgRESTのDockerイメージを取得します。

と思ったのだけど、

github.com

Since the docker image is minimal, it does not contain a shell or other utilities. To derive a non-minimal image, you can do the following:

# derive from any base image you want
FROM alpine:latest

# copy PostgREST over
COPY --from=postgrest/postgrest /bin/postgrest /bin

# add your other stuff

https://github.com/PostgREST/postgrest/tree/main/nix/tools/docker

⇧ というわけで、気付かずに無茶苦茶ハマった...

要するに、

docker pull postgrest/postgrest

⇧ を実行すると、シェルが含まれないDockeイメージが取得されて、Dockerコンテナにログインできない...

軽量化したかったのか知らんけど、気付きにくいから、目立つとこで説明して欲しい...

致し方無いので、DockerfileからDockerイメージを作る感じになるかと。

Dockerコンテナにログインできなくても問題ないのであれば、docker pullでDockerイメージを取得するで問題ないと思われます。

あと、OSイメージによっては、cgroupのバージョンの問題でコンテナの動作で失敗するので要注意ですかね。

ネットの情報を調べた感じでは、cgroupのバージョンが、

  • cgroup v1
  • cgroup v2

の2つがあるようで、「Rancher Desktop」でDocker使っている場合、2023年8月11日(金)時点だと、「cgroup v1」のみ対応って感じになるかと。「Rancher Desktop」のバージョンによっても変わってくるのかも知らんけど。

話が脱線しましたが、適当な場所に、Dockerfileを作成。

PostgRESTを構築するためのDockerfileの中身。

FROM registry.access.redhat.com/ubi9/ubi-minimal:latest

RUN microdnf update -y --disableplugin=subscription-manager \
 && microdnf install dnf -y \
 && dnf update -y \
 && dnf clean all -y \
 && dnf install -y zip \
 && dnf install -y git \
 && dnf install -y findutils \
 && dnf install -y sudo \
 && dnf install -y iproute \
 && dnf install -y bind-utils \
 && dnf install -y vim \
 && dnf install -y systemd dbus \
 && dnf install -y hostname \
 && dnf install -y procps

#RUN sudo mkdir /sys/fs/cgroup/systemd:
#RUN sudo systemctl disable firewalld

WORKDIR /usr/project
VOLUME /tmp

# copy PostgREST over
COPY --from=postgrest/postgrest /bin/postgrest /bin

EXPOSE 3000

RUN groupadd dev_web && useradd dev_web -g dev_web -p $(perl -e 'print crypt("password", "\$6\$salt03")') 
RUN usermod -aG wheel dev_web
USER dev_web

CMD [ "/bin/postgrest" ]

そしたらば、Dockerfileを元に、Dockerイメージを作成。

docker build -t postgrest:latest .

⇧ PostgRESTのDockerイメージが取得できました。そしたらば、PostgRESTのDockerイメージを元に、PostgRESTのDockerコンテナを作成・起動で。

genchan.net

⇧ Dockerコンテナにホスト名を付けた方が良さそうな気がするので、ホスト名を付けてDockerコンテナを作成・起動することにします。

ホスト名については、

suu-g.hateblo.jp

⇧ 上記サイト様が詳しいです。

PostgRESTのDockerコンテナを作成・起動の前に、「WSL 2(Windows SubSystem for Linux 2)」のUbuntuPostgreSQLがインストールされている)を起動しておきます。

「WSL 2(Windows SubSystem for Linux 2)」のUbuntuPostgreSQLがインストールされている)のIPアドレスを確認。

IPアドレスが確認できたので、PostgRESTのDockerコンテナを作成・起動します。

docker run -it --name postgrest-api-server -h postgrest-api-server --add-host=ubuntuhost:172.24.91.141 --dns=8.8.8.8 --privileged -p 3000:3000 -e PGRST_DB_URI="postgres://dev_web:password@ubuntuhost/sample" -e PGRST_DB_ANON_ROLE="dev_web" postgrest:latest

そしたらば、EclipseでSpring Bootのアプリケーションを起動。

で、Postmanからリクエストを送信。

⇧ 結果が返ってきているので、PostgRESTを経由して、PostgreSQLからデータを引っ張て来れているようです。

計算処理とかする場合は、JSONのままじゃできないと思うので、Java以外の言語にしても、どっちにしろオブジェクトなどにマッピングするための変換処理の必要があるとは思う...

結局のところ、データベースを使っている以上、ORM的なデータの変換処理は避けられないような気がする...

毎度モヤモヤ感が半端ない...

今回はこのへんで。