この記事では、APIとREST APIに慣れ親しみ、その後、独自のFlask REST APIアプリケーションを構築していきます。
APIとは?
API (Application Programming Interface) は、異なるアプリケーションと対話するためのインターフェイスを提供します。
APIを使用すると、他のアプリケーションからデータ – 値を取得したり、処理したり、送信したりすることができます。
例えば、Webアプリケーションを考えてみましょう。
クライアントがあるデータをリクエストとして送信すると、サーバーはそれを処理し、適切なレスポンスデータをクライアントに送り返します。
この一連のやり取りは、APIを介して行われます。
では、この例をもう一度見て、APIの役割がどこにあるのかを見てみましょう。
したがって、クライアントがサーバーに送るのは、リクエストデータを含むAPIです。
サーバーはそれを処理し、適切なレスポンスデータを含む別のAPIをクライアントに送り返す。
CRUD演算子とHTTPメソッド
APIを使用する際、クライアントはさまざまな方法でサーバーにリクエストデータを送信することができます。
これらのタイプは、CRUD操作と呼ばれます。
各CRUD(Create Retrieve Update Delete)演算子には、それに関連するHTTPメソッドがあります。
それでは、それらについて見ていきましょう。
- GET HTTPメソッド-サーバーから特定の情報(表示目的)を取得します。
- POST – サーバーデータベースに新しい情報を送信/作成します。
- PUT – データベース内の情報を編集/更新するか、まだ存在しない場合はそれを追加します。
- DELETE – サーバーデータベースから情報を削除します。
さて、メソッドがわかったところで、それぞれのメソッドをいつ使うかを理解しましょう。
次のような例を考えてみましょう。
名前、クラス、年齢などの情報を含む学生データベースがあります。
- 生徒のリストを見るには – GET HTTP メソッドを使用します。
- 新しい学生情報を追加するには – POST HTTPメソッドを使用してください。
- 生徒の特定の情報(クラス/年齢)を編集するには – PUT HTTPメソッドを使用してください。
- データベースから生徒の情報を削除するには、DELETE HTTP メソッドを使用します。
REST API とは何ですか?
REST (Representational State Transfer) APIは、標準的なAPIと似ています。
ここで、サーバーにリクエストを送ると、データで応答するAPIとは異なり、REST APIはリソースで応答します。
REST API のリソース
さて、リソースとは何でしょうか?
まあ、リソースはデータなんだけど、見方が変わる。
リソースは、オブジェクト指向プログラミングに似ています。
以下の例で理解しましょう。
Flask のビュー、”/Book/Book123″ を考えてみましょう。
ここで、同じView Endpointで4つのアクションを実行することができます。
- GET Book/Book123: Book123 “の情報を表示します。
- POST Book/Book123: 新しい本 “Book123” を作成します。
- PUT Book/Book123: ブック “Book123 “の情報を更新/編集します。
- DELETE Book/Book123: ブック “Book123 “の情報を更新/編集します。データベースから “Book123 “を削除します。
1つの実体が複数の機能(OOPメソッド)を持つので、Bookリソースと考えることができる。
したがって、ClientとServerの間のやりとりは、個々のエンドポイントリクエストではなく、リソース(異なるアクションのための同じエンドポイントを持つ)です。
REST APIのステートレス化
REST APIのもう一つの特徴は、ステートレスであることです。
これはどういうことかというと、サーバーが1つのアクションを完了した後、そのことを忘れてしまうということです。
これを例で理解しましょう。
上で見たBook Resourceを考えてみましょう。
Stephen Hawkings の ” A Brief History Of Time ” という本に関するデータを POST メソッドで送信したとします。
サーバーはこの情報をデータベースに追加し、そのアクションを忘れます。
次に私が GET リクエストでその本を取得するとき、サーバは前回の POST メソッドの動作を全く覚えていないことになります。
サーバーはまずデータベースにアクセスし、Bookを探します。
そして、Bookを見つけたら、そのデータで応答します。
そして、アクションを完了した後は、そのことを忘れます。
クライアントとサーバーのAPIインタラクションにおけるJSONの使用
APIは、リクエストの受け付けと返信にJSON形式を使用します。
つまり、クライアントはリクエストデータをJSONテキストとしてサーバーに送信します。
同様に、サーバーはそのデータを処理し、再びJSONテキストとして応答を返します。
従って、REST APIを利用したWebアプリケーションの全体の流れは、以下のようになります。
- ユーザーはリクエストデータをJSONとしてサーバーに送信します。
- サーバーは、まずJSONをPythonで読める形式に変換します。
- サーバーはまずJSONをpythonで読める形式に変換します。
- そして、WebページのTemplateがJSONのレスポンスをユーザーが読める形式に変換し、Webページに表示します。
このように、APIにおけるクライアント側(FRONT-END)とサーバー側(BACK-END)の実際の情報のやりとりは、JSONテキストを使って行われます。
JSON形式は、Pythonの辞書に似ています。
{ 'student1' :{
'name' : 'XYZ' ,
'age' : 21
}
} |
この記事もチェック:Flaskにおけるアプリケーションコンテキストとリクエストコンテキストを解説する
POSTMANのインストール
Postman は API 開発のためのコラボレーションプラットフォームです。
Postmanの機能はAPI構築の各ステップを簡素化し、コラボレーションを効率化するので、より良いAPIをより早く作成することができます。
POSTMANをダウンロードするには、ここをクリックしてください。
インストールすると、以下のようになります。
pip install flask_restful
|
さて、コーダーの皆さん! それでは、REST APIの構築を始めましょう。
Flask REST API アプリケーションの構築
このセクションでは、Flask の RESTFul ライブラリを使用して、シンプルな Book REST API アプリケーションを構築します。
1. Flask_Restful のシステムへのインストール
FlaskのRestFullパッケージをインストールするために、pipコマンドを実行します。
pip install flask_sqlalchemy
|
これでインストールが完了したので、次はデータベース編です。
2. SQLAlchemy を使った DB モデルのコード化
ここでは、モデルを格納するために SQLite データベースを使用します。
使用するには、まず flask_sqlalchemy をインストールします。
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class BookModel(db.Model):
__tablename__ = 'books'
id = db.Column(db.Integer, primary_key = True )
name = db.Column(db.String( 80 ))
price = db.Column(db.Integer())
author = db.Column(db.String( 80 ))
def __init__( self , name, price, author):
self .name = name
self .price = price
self .author = author
def json( self ):
return { "name" : self .name, "price" : self .price, "author" : self .author}
|
models.py ファイルを作成し、以下のコードを追加します。
from flask import Flask
from flask_restful import Api
app = Flask(__name__)
api = Api(app) #Flask REST Api code
if __name__ = = '__main__' :
app.run(host = 'localhost' , port = 5000 )
|
ここでは、BookModelにname、price、authorのフィールドを追加しています。
APIはJSONなので、JSONのブックオブジェクトを返すために、Objectメソッド.json()を作成します。
まず、DBモデルを作成するために、DBインスタンスをインスタンス化する必要があります。
SQLAlchemy について疑問があれば、 SQLAlchemy チュートリアルを参照してください。
さて、モデルができたので、Flaskアプリケーションのメインコードを書いてみましょう。
この記事もチェック:Flaskのライブラリflask-wtfの使い方|簡単にフォームを作成するよ
3. Flask アプリケーションのコード化
Flask REST API では、Flask に REST API の Web アプリであることを示すために、API(app) インスタンスを追加する必要があります。
app.config[ 'SQLALCHEMY_DATABASE_URI' ] = 'sqlite:///<db_name>.db'
app.config[ 'SQLALCHEMY_TRACK_MODIFICATIONS' ] = False
db.init_app(app) |
次に、SQLAlchemy に SQLite の情報を与えて、DB インスタンス(フォーム models.py)をこのアプリケーションファイルにリンクさせる必要があります。
そのために、次のコードを追加します。
@app .before_first_request
def create_table():
db.create_all()
|
ここで、 を任意の DB 名に置き換えてください。
SQLALCHEMY_TRACK_MODIFICATIONSは、シンプルにするためにFalseのままです。
3行目は、DBインスタンスとアプリをリンクしています。
ウェブページのユーザーが使用できるように、DBファイルを配置する必要があります。
また、最初のユーザー・リクエストの前にも必要です。
そこで、ファイルを作成するために、この関数を使用します。
class BooksList(Resource):
def get( self ):
#get all objects from BookModel
#return the JSON text of all objects
pass
def post( self ):
#convert the JSON data sent by the user to python-format
#create a new bookModel object and send in the data
#save to DB
pass
|
これを上記のコードの下に追加してください。
さて、これでFlask REST API Resource Classesのコーディングができました。
この記事もチェック:Flaskでフォームを実装|ユーザーの入力を受け取る方法などを解説
4. 書籍リストリソースを追加する
このリソースは以下のようなものです。
- GETメソッド:DBに登録されている書籍の一覧を表示します。
- POSTメソッド : 新しい書籍情報をDBに追加する
というわけで、コードは以下のようになります。
class BooksList(Resource):
def get( self ):
books = BookModel.query. all ()
return { 'Books' : list (x.json() for x in books)}
def post( self ):
data = request.get_json()
new_book = BookModel(data[ 'name' ],data[ 'price' ],data[ 'author' ])
db.session.add(new_book)
db.session.commit()
return new_book.json(), 201
|
というわけで、上に書いたようなタスクができるコードになるはずです。
では、コメントを実際のコードに置き換えてみましょう。
api.add_resource(BooksView, '/books' )
|
ここでは、GETメソッドを使用しています。
- BookModle.query.all()を使ってDBに存在する本を取得します。
- 本のJSONテキストを1つずつリストで表示します。
POSTメソッドでは
- request.get_json()を使ってJSONデータを変換します。
- 新しいBookの情報を作成し、DBに追加します。
以上、最後にBooksList ResourceのURLエンドポイントを記載します。
class Book(Resource):
def get( self ,name):
#get the book with the name given by the user
#if book exists, return it else return 404 not found
def put( self ,name):
#convert the JSON data sent by the user to python-format
#Search if the book exists
#if it exists, update it with the data given by the user
#if does not exists, create and add the book into DB
def delete( self ,name):
#Search if the book exists in the DB
#delete it
|
5. 本のリソースを追加する
では、次のようなリソースを作成します。
- GETメソッド。GETメソッド: ユーザーがリクエストした特定の本だけを表示する
- PUTメソッド。PUTメソッド:特定の書籍の情報を編集します。存在しない場合は、作成する
- DELETE メソッド。特定のブックを削除する
ここでは、以下のようなコードになります。
class Book(Resource):
def get( self ,name):
book = BookModel.query.filter_by(name = name).first()
if book:
return book.json()
return { 'message' : 'book not found' }, 404
def put( self ,name):
data = request.get_json()
book = BookModel.query.filter_by(name = name).first()
if book:
book.price = data[ "price" ]
book.author = data[ "author" ]
else :
book = BookModel(name = name, * * data)
db.session.add(book)
db.session.commit()
return book.json()
def delete( self ,name):
book = BookModel.query.filter_by(name = name).first()
if book:
db.session.delete(book)
db.session.commit()
return { 'message' : 'Deleted' }
else :
return { 'message' : 'book not found' }, 404
|
このコードは、上記のすべてのタスクを実行できるようにする必要があります。
そこで、コードを追加します。
api.add_resource(BookView, '/book/<string:name>' )
|
GET メソッドの中で
- BookModel.query.filter_by(name=name).first() は、DBから取得した最初の本を返します。その名前を持つものが見つからなかった場合は None を返します。
- 見つかった場合は、本のJSONテキストを返します。さもなくば404を返す。
PUTメソッドの場合。
- request.get_json()でJSONデータを変換します。
- その名前の本を検索します。
- 存在する場合は、古いデータを新しく送信されたデータで置き換える。
- さもなければ、新しいBookオブジェクトを作成する
- DBに追加する
DELETEメソッドでは
- ユーザが指定した名前の本を取得します。
- それを削除する
これで終わりです。
最後に、このResourceのURLエンドポイントを追加します。
from flask import Flask,request
from flask_restful import Api, Resource, reqparse
from models import db, BookModel
app = Flask(__name__)
app.config[ 'SQLALCHEMY_DATABASE_URI' ] = 'sqlite:///data.db'
app.config[ 'SQLALCHEMY_TRACK_MODIFICATIONS' ] = False
api = Api(app)
db.init_app(app) @app .before_first_request
def create_table():
db.create_all()
class BooksView(Resource):
'''
parser = reqparse.RequestParser()
parser.add_argument('name',
type=str,
required=True,
help = "Can't leave blank"
)
parser.add_argument('price',
type=float,
required=True,
help = "Can't leave blank"
)
parser.add_argument('author',
type=str,
required=True,
help = "Can't leave blank"
)'''
def get( self ):
books = BookModel.query. all ()
return { 'Books' : list (x.json() for x in books)}
def post( self ):
data = request.get_json()
#data = BooksView.parser.parse_args()
new_book = BookModel(data[ 'name' ],data[ 'price' ],data[ 'author' ])
db.session.add(new_book)
db.session.commit()
return new_book.json(), 201
class BookView(Resource):
'''
parser = reqparse.RequestParser()
parser.add_argument('price',
type=float,
required=True,
help = "Can't leave blank"
)
parser.add_argument('author',
type=str,
required=True,
help = "Can't leave blank"
)'''
def get( self ,name):
book = BookModel.query.filter_by(name = name).first()
if book:
return book.json()
return { 'message' : 'book not found' }, 404
def put( self ,name):
data = request.get_json()
#data = BookView.parser.parse_args()
book = BookModel.query.filter_by(name = name).first()
if book:
book.price = data[ "price" ]
book.author = data[ "author" ]
else :
book = BookModel(name = name, * * data)
db.session.add(book)
db.session.commit()
return book.json()
def delete( self ,name):
book = BookModel.query.filter_by(name = name).first()
if book:
db.session.delete(book)
db.session.commit()
return { 'message' : 'Deleted' }
else :
return { 'message' : 'book not found' }, 404
api.add_resource(BooksView, '/books' )
api.add_resource(BookView, '/book/<string:name>' )
app.debug = True
if __name__ = = '__main__' :
app.run(host = 'localhost' , port = 5000 )
|
これで完了です!
Flask Rest API アプリケーションの最終コード
というわけで、Flaskのメインアプリケーションを組み合わせたものは以下のようになります。
from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy()
class BookModel(db.Model):
__tablename__ = 'books'
id = db.Column(db.Integer, primary_key = True )
name = db.Column(db.String( 80 ))
price = db.Column(db.Integer())
author = db.Column(db.String( 80 ))
def __init__( self , name, price, author):
self .name = name
self .price = price
self .author = author
def json( self ):
return { "name" : self .name, "price" : self .price, "author" : self .author}
|
models.py ファイルです。
{ "name" : "book1" ,
"price" : 123 ,
"author" : "author1"
} |
それでは、POSTMANを使ってサーバを起動し、確認してみましょう。
POSTMANを使ったFlask REST APIアプリケーションの実装
サーバーを起動し、POSTMANにアクセスします。
1. BooksList リソース:POST メソッド
POSTメソッドで”/books “エンドポイントに移動します。
ボディでraw – JSONを選択し、JSONデータをボディに追加します。
{ "price": 100,
"author":"author123"
} |
送信
Book – book1が作成されます。
2. BooksList リソース:POST メソッド
GETメソッドで “books/”にアクセスし、送信を押してください。
DBに登録されている書籍の一覧が表示されます。
book1しかないので、リストに表示されているのは1件だけです。
3. 書籍のリソース:GETメソッド
GETメソッドで”/books/book1 “にアクセスし、送信をクリックします。
Book1の情報が表示されます。
4. 書籍資源:PUTメソッド
PUTメソッドで”/books/book1 “にアクセスし、本文に以下のJSONを追加してください。
名前はすでにURLリクエストで送信されているので、価格と著者のJSONを送信する必要があります。
送信を実行
価格と著者の値が変更されました。
GETメソッドでも確認してみてください。
5. 書籍資源:DELETEメソッド
DELETEメソッドで「/books/book1」に移動します。
削除されたことを確認
まとめ
以上です。
Flask REST APIフレームワークについて、十分な知識を得ることができたのではないでしょうか。
より深く理解するために、上記のコードを自分で試してみてください。
それではまた次回!