📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)

 
(同じ利用者による、間の6版が非表示)
1行目: 1行目:
== 概要 ==
== 概要 ==
REST APIは、HTTPプロトコルを使用して、クライアントとサーバ間でリソースのやり取りを行うインターフェースである。<br>
主なHTTPメソッド (GET、POST、PUT、DELETE) を使用して、リソースの取得、作成、更新、削除等の操作を実現する。<br>
<br>
サーバの実装において、Linuxディストリビューションに必要なプログラム言語とフレームワークをインストールする。<br>
一般的な選択肢としては、PythonのFlaskやDjango、Node.jsのExpress、RubyのRails、JavaのSpring Boot等がある。<br>
<br>
以下の例では、PythonのFlaskを使用した基本的なREST APIを構築している。<br>
<syntaxhighlight lang="python">
from flask import Flask, request, jsonify
app = Flask(__name__)
# データストアの代わりとなる簡単なディクショナリ
books = {}
@app.route('/api/books', methods=['GET'])
def get_books():
    return jsonify(books)
@app.route('/api/books', methods=['POST'])
def add_book():
    book = request.get_json()
    books[len(books) + 1] = book
    return jsonify({'message': 'Book added successfully'})
if __name__ == '__main__':
    app.run(debug=True)
</syntaxhighlight>
<br>
セキュリティでは、APIキーの実装、HTTPS通信の設定、入力データのバリデーション、SQLインジェクション対策等を行う必要がある。<br>
また、認証・認可の仕組みとして、JWTトークンやOAuth2.0の実装も検討する必要がある。<br>
<br>
パフォーマンスとスケーラビリティでは、キャッシュの実装 (例: Redis)、データベースの最適化 (インデックス設計等)、ロードバランサの設置が重要である。<br>
また、コンテナ化 (Podman等) やオーケストレーション (Kubernetes) の導入も検討する。<br>
<br>
APIのドキュメント化も重要な要素となる。<br>
Swagger / OpenAPIを使用することにより、APIの仕様を明確に定義して、自動的にドキュメントを生成することができる。<br>
これにより、他の開発者がAPIを理解および使用することが容易になる。<br>
<br>
モニタリングとログ収集の設定において、PrometheusやGrafanaを使用してメトリクスを収集・可視化して、<br>
ELKスタック (Elasticsearch、Logstash、Kibana) でログを収集・分析することにより、APIの健全性を監視することができる。<br>
<br>
<br>
REST APIサーバを構築・運用する場合は、以下に示す事柄に注意する。<br>
REST APIサーバを構築・運用する場合は、以下に示す事柄に注意する。<br>
38行目: 79行目:
Pythonと仮想環境をインストールする。<br>
Pythonと仮想環境をインストールする。<br>
  # RHEL
  # RHEL
  sudo dnf install python3 python3-pip python3-venv
  sudo dnf install python3 python3-pip python3-virtualenv
   
   
  # SUSE
  # SUSE
47行目: 88行目:
<br>
<br>
Pythonと仮想環境の設定を行う。<br>
Pythonと仮想環境の設定を行う。<br>
  python3 -m venv venv
これにより、プロジェクトごとに独立したPython環境を作成することができる。<br>
  python3 -m venv <作成する仮想環境のディレクトリ名>
<br>
<br>
vi ~/.profile
Pythonの仮想環境をアクティベートする。<br>
<br>
# ~/.profileファイル
  source venv/bin/activate
  source venv/bin/activate
<br>
<br>
必要なPythonライブラリをインストールする。<br>
必要なPythonライブラリをインストールする。<br>
  pip install fastapi uvicorn sqlalchemy
  pip install fastapi uvicorn sqlalchemy
<br>
<u>※注意</u><br>
<u>venv/bin/activateスクリプトを~/.profileファイル等に設定することは非推奨である。</u><br>
* <u>activateスクリプトは相対パスで動作するため、フルパスで指定する必要がある。</u>
* <u>常に特定の仮想環境がアクティブになってしまうため、他のプロジェクトで異なる仮想環境を使用する場合に問題が発生する。</u>
* <u>シェルのセッションごとに自動的にアクティベートすると、どの環境で作業しているのか理解しにくい。</u>
<br>
<u>代替案として、以下に示すような方法が推奨される。</u><br>
<u>以下に示すような方法ならば、必要な時のみ仮想環境をアクティベートすることが可能なため、柔軟な運用が可能になる。</u><br>
<br>
<u>特に、複数のプロジェクトを扱う場合は、2番目や3番目の方法が便利である。</u><br>
<br>
<syntaxhighlight lang="sh">
# 方法 1
# エイリアスを設定する方法 (~/.profileファイル等に記述)
alias activate-myproject='source <activateスクリプトのパス>'
</syntaxhighlight>
<br>
<syntaxhighlight lang="sh">
# 方法 2
# プロジェクトディレクトリに入った時のみ自動的にアクティベートする方法 (~/.profileファイル等に記述)
function cd()
{
    builtin cd "$@"
    # プロジェクトディレクトリに入った時のみ仮想環境をアクティベート
    if [ -d "venv" ]; then
      # 既に仮想環境がアクティブでない場合のみ
      if [ -z "$VIRTUAL_ENV" ]; then
          source venv/bin/activate
      fi
    fi
}
</syntaxhighlight>
<br>
<syntaxhighlight lang="sh">
# 方法 3
# direnvのような専用ツールを使用する方法
# プロジェクトディレクトリの.envrcファイルに記述
layout python3  # Pythonの仮想環境を自動的に管理
</syntaxhighlight>
<br>
<br>
==== Node.js + Expressを使用する場合 ====
==== Node.js + Expressを使用する場合 ====
84行目: 167行目:
<br>
<br>
データベースを作成する。<br>
データベースを作成する。<br>
  sudo -u postgres createdb myapi_db
  sudo -u postgres createdb   <任意のデータベース名>
  sudo -u postgres createuser myapi_user
  sudo -u postgres createuser <任意のデータベースユーザ名>
<br>
==== MariaDBを使用する場合 ====
===== MariaDBのインストール =====
MariaDBをインストールする。<br>
# RHEL
sudo dnf install
# SUSE
sudo zypper install
# Raspberry Pi
sudo apt install mariadb-server mariadb-client
<br>
MariaDBのセキュリティを設定する。<br>
* rootパスワードの設定
* anonymousユーザの削除
* リモートrootログインの禁止
* テストデータベースの削除
* 権限テーブルの再読み込み
<br>
sudo mysql_secure_installation
<br>
MariaDBへログインして、データベースの作成、ユーザの作成、権限の設定を行う。<br>
sudo mysql -u root -p
# データベースとユーザの作成
CREATE DATABASE <<任意のデータベース名>;
CREATE USER '<任意のデータベースユーザ名>'@'localhost' IDENTIFIED BY '<データベースユーザのパスワード>';
# 権限の設定
GRANT ALL PRIVILEGES ON <<任意のデータベース名>.* TO '<任意のデータベースユーザ名>'@'localhost';
# 設定を反映
FLUSH PRIVILEGES;
<br>
MariaDB向けPythonドライバをインストールする。<br>
pip install mysql-connector-python sqlalchemy mysqlclient
# または
pip3 install mysql-connector-python sqlalchemy mysqlclient
<br>
必要な場合は、MariaDBのパフォーマンスの最適化を行う。<br>
<syntaxhighlight lang="ini">
[mysqld]
# バッファプールサイズ (利用可能メモリの50-70[%]程度)
innodb_buffer_pool_size = 1G
# クエリキャッシュ
query_cache_type = 1
query_cache_size = 128M
# 接続数の設定
max_connections = 150
# スレッドキャッシュ
thread_cache_size = 8
# テーブルオープンキャッシュ
table_open_cache = 2000
# InnoDBの設定
innodb_file_per_table          = 1
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size        = 16M
</syntaxhighlight>
<br>
===== バックアップ設定 =====
バックアップスクリプトを作成する。<br>
<br>
<syntaxhighlight lang="sh">
#!/usr/bin/env sh
BACKUP_DIR="<任意のバックアップディレクトリ  例: /var/backups/mysql>"
BACKUP_FILE="<任意のバックアップファイル名  例: myapi_db>"
DATE=$(date +%Y%m%d_%H%M%S)                      # 日付を付加する場合
BACKUP_FILE="$BACKUP_DIR/$BACKUP_FILE_$DATE.sql"  # バックアップファイルのパス
# バックアップの作成
# 例: mysqldump -u myapi_user myapi_db > $BACKUP_FILE
mysqldump -u <データベースユーザ名> <データベース名> > $BACKUP_FILE
# 圧縮
gzip $BACKUP_FILE
# 30日以上前のバックアップを削除 (オプション)
find $BACKUP_DIR -name "*.sql.gz" -mtime +30 -delete
</syntaxhighlight>
<br>
===== MariaDBのメンテナンス =====
定期的な実行が推奨されるメンテナンスを行う。<br>
<br>
<syntaxhighlight lang="mysql">
-- テーブルの分析
ANALYZE TABLE items;
-- テーブルの最適化
OPTIMIZE TABLE items;
-- インデックスの使用状況確認
SHOW INDEX FROM items;
-- スロークエリの確認
SHOW VARIABLES LIKE '%slow%';
SHOW VARIABLES LIKE '%long%';
</syntaxhighlight>
<br><br>
<br><br>


== APIの基本的な実装 ==
== APIの基本的な実装 ==
==== Python + FastAPIを使用する場合 ====
==== Python + FastAPIを使用する場合 ====
以下に示すソースコードはサーバサイドであり、APIサーバ内部で動作する部分である。<br>
したがって、クライアントが直接触れる部分ではなく、APIサーバの内部実装として機能する。<br>
<br>
クライアントは以下に示すソースコードを意識することなく、定義されたAPIエンドポイントを通じてデータの操作を行うことが可能となる。<br>
<br>
===== PostgresSQLを使用する場合 =====
  <syntaxhighlight lang="python">
  <syntaxhighlight lang="python">
  # main.pyファイル
  # main.pyファイル
109行目: 302行目:
  async def create_item(item: Item):
  async def create_item(item: Item):
     return item
     return item
</syntaxhighlight>
<br>
===== MariaDBを使用する場合 =====
以下の例では、APIサーバがMariaDBと通信するための設定を行う。<br>
* データベースへの接続設定
* コネクションプールの管理
* セッション管理の設定
<br>
<syntaxhighlight lang="python">
# database.py
# SQLAlchemyを使用したデータベース接続設定
from sqlalchemy import create_engine
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import sessionmaker
SQLALCHEMY_DATABASE_URL = "mysql+mysqlconnector://myapi_user:your_password@localhost/myapi_db"
engine = create_engine(
    SQLALCHEMY_DATABASE_URL,
    pool_size=5,
    max_overflow=10,
    pool_timeout=30,
    pool_recycle=1800
)
SessionLocal = sessionmaker(autocommit=False, autoflush=False, bind=engine)
Base = declarative_base()
</syntaxhighlight>
<br>
以下の例では、データベースのテーブル構造をPythonのクラスとして定義している。<br>
* データベーステーブルの構造定義
* SQLAlchemyによるORMマッピング
* テーブルのカラム定義とその制約
<br>
<syntaxhighlight lang="python">
# models.py
# モデルの定義例
from sqlalchemy import Column, Integer, String, DateTime
from sqlalchemy.sql import func
from database import Base
class Item(Base):
    __tablename__ = "items"
    id = Column(Integer, primary_key=True, index=True)
    name = Column(String(100), nullable=False)
    description = Column(String(500))
    created_at = Column(DateTime(timezone=True), server_default=func.now())
    updated_at = Column(DateTime(timezone=True), onupdate=func.now())
</syntaxhighlight>
<br>
これらをREST APIサーバとして使用する場合、以下に示すような構成となる。<br>
<syntaxhighlight lang="python">
# main.py (APIエンドポイントの定義)
from fastapi import FastAPI, Depends
from sqlalchemy.orm import Session
from . import models, database
app = FastAPI()
# データベースセッションの依存性注入 (DIコンテナ)
def get_db():
    db = database.SessionLocal()
    try:
      yield db
    finally:
      db.close()
# APIエンドポイント例
@app.post("/items/")
def create_item(name: str, description: str, db: Session = Depends(get_db)):
    db_item = models.Item(name=name, description=description)
    db.add(db_item)
    db.commit()
    db.refresh(db_item)
    return db_item
</syntaxhighlight>
<br>
REST APIサーバの情報を取得する場合は、クライアントからREST APIエンドポイントに対してHTTPリクエストを送信する。<br>
<syntaxhighlight lang="sh">
# クライアントからのAPIリクエスト例
curl -X POST "http://your-server/items/" \
      -H "Content-Type: application/json" \
      -d '{"name": "テスト項目", "description": "説明文"}'
  </syntaxhighlight>
  </syntaxhighlight>
<br><br>
<br><br>


== HTTPS対応 ==
== HTTPS対応 ==
120行目: 401行目:
   
   
  # SUSE
  # SUSE
  sudo zypper install ca-certificates python3-certbot
  sudo zypper install python3-certbot python3-certbot-nginx
   
   
  # Raspberry Pi
  # Raspberry Pi
191行目: 472行目:
   
   
  sudo wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key
  sudo wget -q -O /usr/share/keyrings/grafana.key https://apt.grafana.com/gpg.key
<br>
MariaDBを使用している場合は、MySQLエクスポータ (Prometheus向け) をインストールする。<br>
sudo apt install prometheus-mysqld-exporter
<br>
MySQLエクスポータ (Prometheus向け) の設定ファイルを作成する。<br>
sudo vi /etc/default/prometheus-mysqld-exporter
<br>
# /etc/default/prometheus-mysqld-exporterファイル
# 例: DATA_SOURCE_NAME="myapi_user:your_password@(localhost:3306)/"
DATA_SOURCE_NAME="<データベースユーザ名>:<データベースユーザのパスワード>@(localhost:<MariaDBのポート番号>)/"
<br><br>
<br><br>