FastAPIの基礎(+α Routing)

最近人気のPythonWebフレームワーク『**FastAPI**』の基本的な内容について記載してます。
また、Routingの処理を別ファイルへと記載するやり方も載せてます。

# インストール
以下のpip installを実行(Terminal等で実行)
```
pip install fastapi uvicorn
```
環境構築はこれでおしまい。

# Hello world
まず、ざっとHello worldが表示されるコードを以下に記載してみた。
内容については後ほど詳しく。

```python
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

origins = ["http://localhost:3000",]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

@app.get("/")
def Hello():
    return {"Hello":"World!"}
```

以下を叩く。
```
uvicorn index:app --reload
```
そして、この画面がでればひとまずFastAPI完成。
[http://127.0.0.1:8000](http://127.0.0.1:8000
 "http://127.0.0.1:8000")
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516848/a1a6e1ec-5483-ccb0-f904-31172be78e5a.png)

それでは、上で書いたHello worldのコードについて詳しく説明していく。

### 1. import部分
```python
from fastapi import FastAPI
```
これは言わずもがな、FastAPIを使うためのもの

```python
from fastapi.middleware.cors import CORSMiddleware
```
こっちは、ミドルウェアの設定を行うためのもの。
要はタイムアウト処理を入れたり、クロスサイトHttpリクエスト（フロントからのFastAPIアクセス）を許可したりするもの。

### 2. FastAPI設定部分
```python
origins = ["http://localhost:3000",]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
```
originsにフロントからアクセスができるURLを格納（ホワイトリスト）。
詳しい内容については、↓↓↓の方がCross Originでつまづいた際の記事があるので参考に
[FastAPIでCORSを回避](https://qiita.com/satto_sann/items/0e1f5dbbe62efc612a78
 "FastAPIでCORSを回避")

正直ここはFastAPIをURLから直接叩くだけであれば、必要なかったり（不要とは言ってない...）


### 3. router部分
```python
@app.get("/")
def Hello():
    return {"Hello":"World!"}
```
ここはさらに細かく説明すると、

```python
@app.get("/")
```
これは「[http://127.0.0.1:8000](http://127.0.0.1:8000
 "http://127.0.0.1:8000")」以降のURLを指している。
今回だと「[http://127.0.0.1:8000](http://127.0.0.1:8000
 "http://127.0.0.1:8000")」もしくは、「[http://127.0.0.1:8000/](http://127.0.0.1:8000
 "http://127.0.0.1:8000/")」で
下の関数を実行しますよというものである。
```python
def Hello():
    return {"Hello":"World!"}
```

つまり、以下のようにした場合は、
```python
@app.get("/Hello")
```
「[http://127.0.0.1:8000/Hello](http://127.0.0.1:8000/Hello
 "http://127.0.0.1:8000/Hello")」と叩かなくてはならない。


とりあえずざっと説明したが、postの場合についても触れておく。
post時のrequestの受け方はいろんなやり方があるが、個人的に好きな方法としては、Classを定義しといてそれを受け取るやり方。

この方法でやるなら、追加でinstallが必要。
```
pip install pydantic
```

```python
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class Request(BaseModel):
    test_id:int = 0
    test_name:str = ''

class Response(BaseModel):
    status_code:int = 200
    message:str = ''

@app.post('/post')
def post_test(request:Request):
    print(request.test_id)
    print(request.test_name)
    return Response()
```
BaseModelを継承したRequestクラスを受け取り、BaseModelを継承したResponseのインスタンスで返却する方法。
これでとりあえず、PostによるRequest、Responseの授受が完成。
※RequestとかResponseとかクラス名にしてるけど、変更してください


今回は、GetとPostの１個ずつだったが、２個、３個、４個、、、、、、、と増えていくと1つのファイルにすごい量書くことになるので、別ファイルでのrouting処理を記載するやり方を記載する。

## 別ファイルでRouting処理
まず、最初にindex.pyを作成する
```index.py
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
app.include_router(hello.router) # 別ファイルをimport

app = FastAPI()

origins = ["http://localhost:3000",]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

app.include_router(NavigationRouter.router) # 別ファイルをinclude
```

次に別ファイルに移したRouting処理
```hello.py
from fastapi import APIRouter

router = APIRouter()

@router.get('/Hello')
def Hello():
    return {'Hello': 'World!'}
```
これで別ファイルになっていても「[http://127.0.0.1:8000/Hello](http://127.0.0.1:8000/Hello
 "http://127.0.0.1:8000/Hello")」を叩けば、以下の画面が表示されるはず。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2516848/a1a6e1ec-5483-ccb0-f904-31172be78e5a.png)

注意するところとしては、
```python
app = FastAPI()
```
の代わりに↓↓↓
```python
router = APIRouter()
```
変更することと、

「**@app**」が「**@router**」に変更されていること。

FastAPI簡単でしたね。