GCP使ってみたいドリブンでYelp API使ったテストサイトを作る
GCPでAPIテストサーバー作りたかった
言語: React, Flask
これにどこからかのapi付けて描画すればいいかなっと思ったけど味気ない (Learn Udonのリンク先は、うどんについて語るwiki)ので
Yelp API使ってこんな感じにした
Yelp api
日本の食べ物系サイトはみんな知ってるし、海外のをちょっと見てるのもよいかなとyelp apiを使った
api keyの取得は簡単。yelp developersに入ってgoogleかfacebookのアカウントで登録すればすぐ発行してくれる
Flask
ディレクトリ構成
app
├── config.py
└── run.py
# run.py
from flask import Flask, request
from flask_cors import CORS
import requests
import config
app = Flask(__name__)
CORS(app)
URL = "https://api.yelp.com/v3/businesses/search"
headers = {'Authorization': f"Bearer {config.API_KEY}"}
@app.route('/')
def ramen_yelp():
payload = {
"term": request.args.get("term", "ramen"),
"location": request.args.get("location", "ny")
}
response = requests.request("GET", URL, headers=headers, params=payload)
return response.json()
if __name__ == "__main__":
app.run(host="0.0.0.0", port=config.PORT, debug=config.DEBUG_MODE)
root('/')の場合はデフォルトでニューヨークのラーメンランキングにしている
configにはflask, gunicornの設定
大事なことはenv変数に入れておく
# config.py
from os import environ
import multiprocessing
PORT = int(environ.get("PORT", 8080))
DEBUG_MODE = int(environ.get("DEBUG_MODE", 1))
API_KEY = environ.get("API_KEY")
bind = ":" + str(PORT)
workers = multiprocessing.cpu_count() * 2 + 1
threads = multiprocessing.cpu_count() * 2
ブラウザ(firefox or chrome)から0.0.0.0:8080に入ると
結果をjsonで吐き出すようになった
GCR (Google Container Registry)に登録
flaskをdocker化してGCRにup
Dockerfileはこんな感じでサクッと
# pull official base image
FROM python:3.8.1-alpine
# set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1
# install dependencies
RUN pip install --upgrade pip
COPY requirements.txt requirements.txt
RUN pip install -r requirements.txt
# set work directory
WORKDIR /usr/src/app
# copy project
COPY ./app .
ENV PORT 80
ENV API_KEY YOUR_API_KEY
CMD ["gunicorn", "run:app", "--config=config.py"]
# requirements.txt
Flask==1.1.1
gunicorn==20.0.4
requests==2.23.0
Flask-Cors==3.0.8
*本番はAPI_KEYをdotenv使ってconfig.pyにまとめる
- gcloudをローカルにインストール(doc)
- GCRの課金を有効にする
次に下記のようにコマンド打てば簡単に登録できる
#!/bin/sh
docker build -t flask-test-gcr
docker tag flask-test-gcr [HOSTNAME]/[PROJECT-ID]/flask-test-gcr
docker push [HOSTNAME]/[PROJECT-ID]/flask-test-gcr
gcloud container images list-tags [HOSTNAME]/[PROJECT-ID]/flask-test-gcr
GCE(Google Compute Engine)
インスタンスをgcpコンソール画面から作成
docker使ってコンテナからすぐデプロイしたい人は下記のチェックとコンテナイメージを忘れずに
GCE VMインスタンス画面の外部IPを http:[IP] にすれば同じ結果が出るようになった!
SSL証明書がない場合は外部IPを https じゃなくて http にしないとダメだよ
このIPアドレスをReactから呼び出すのでメモしておく
FrontはReact
create-react-appというステキなボイラープレートで簡単に
# app-nameは好きな名前で
npx create-react-app app-name
App.jsはほとんどテンプレで、画像やリンク、Yelp.jsのComponentを呼んでいる違いぐらい
// App.js
import React from 'react';
import logo from './logo.svg';
import './App.css';
import Yelp from './Yelp' //←これ
function App() {
return (
<div className="main">
<Yelp />
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="Udon logo" />
<a
className="App-link"
href="https://ja.wikipedia.org/wiki/%E3%81%86%E3%81%A9%E3%82%93"
target="_blank"
rel="noopener noreferrer"
>
Learn Udon
</a>
</header>
</div>
</div>
);
}
export default App;
// Yelp.js
import React, { useEffect, useState } from 'react'
import './Yelp.css'
const Yelp = () => {
const [error, setError] = useState(null)
const [yelpData, setYelpData] = useState({})
useEffect(() => {
const API_URL = 'http://さっきメモした外部IP/'
fetch(API_URL)
.then(res => res.json())
.then(
result => {
setYelpData(result)
})
.catch(e => {
setError(e)
})
}, [])
if (error) {
return (
<div className="Yelp">error</div>
)
} else if (yelpData.businesses) {
const images = yelpData.businesses.map(item => {
return (
< a key={item.id} href={item.url} target="_blank" rel="noopener noreferrer" >
< img
height="150" width="150" crop="fill" radius="20"
src={item.image_url} alt="ramen"
/>
</a >
)
})
return (
<div className="Yelp">
{images}
</div>
)
} else {
return (
<div className="Yelp"></div>
)
}
}
export default Yelp
あとはローカルで起動すればラーメン画像が出てくる
# 起動
yarn start
好きな画像をクリックするとYelpのリンク先にとんで詳細が見れる
- ニューヨークのラーメン屋さんはメニューが豊富。ラーメン一筋でやるのは文化的に合わないのかな
- うどんのSVGがグルグル回ってるのがうっとうしい、良いかは賛否ある