LoginSignup
6
6

More than 3 years have passed since last update.

EC2上でvue+expressの環境構築からAPI通信実装まで

Last updated at Posted at 2020-03-22

バックエンド

EC2インスタンス上でexpressを動かし、アプリケーションのbackend環境を構築する。
ここでは例としてアプリケーションappを作る

環境構築

AMI:Ubuntu18.04、IP:x.x.x.x の場合

$ sudo apt-get update
$ sudo apt-get install nodejs
$ sudo apt-get install npm
$ sudo update-alternatives --install /usr/bin/node node /usr/bin/nodejs 10
$ sudo npm install -g express
$ sudo npm install -g express-generator
$ express --view=pug app
$ cd app
$ npm install
$ npm start
> app@0.0.0 start /home/ubuntu/app
> node ./bin/www

AMI:AmazonLinux2、IP:x.x.x.x の場合

$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.34.0/install.sh | bash
$ . ~/.nvm/nvm.sh
$ nvm install node
$ sudo npm install -g express
$ sudo npm install -g express-generator
$ express --view=pug app
$ cd app
$ npm install
$ npm start
> app@0.0.0 start /home/ubuntu/app
> node ./bin/www

app/bin/wwwファイルでポート番号を指定できる。デフォルトではポート3000なので、ブラウザからアクセスして確認できる。

APIの作成

app下にindex.jsを作成し、以下を記述。

GET
// expressモジュールを読み込む
const express = require('express');

// expressアプリを生成する
const app = express();

// ルート(http://x.x.x.x:3000/)にアクセスしてきたときに「Hello」を返す
app.get('/', (req, res) => res.send('Hello'));

// ポート3000でサーバを立てる
app.listen(3000, () => console.log('Listening on port 3000'));
POST
const express = require('express');
const bodyParser = require('body-parser');

const app = express();

// urlencodedとjsonは別々に初期化する
app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());

app.post('/', function(req, res) {
    console.log(req.body);
    res.send('POST request to the homepage');
})

// ポート3000でサーバを立てる
app.listen(3000, () => console.log('Listening on port 3000'));
$ node index.js # 実行
Listening on port 3000

POSTメソッドでは、body-parserモジュールを用いてJSONで取得する。

テスト

APIを叩く。

ブラウザから(GET)

x.x.x.x:3000/にアクセス。

コンソールから(POST)

POST
$ curl -X POST http://x.x.x.x:3000/ -H "Accept: application/json" -H "Content-type: application/json" -d '{ "name" : "tanaka" }'

フロントエンド

環境構築

vueの環境構築はこちらの記事で書いた通りなので省略。

フロントエンドから外部APIを叩く

デフォルトのAboutページにボタンをつくり、押したら非同期で外部API(httpbin)を叩くようにしてみる。

必要なものをいれる。

$ npm install axios vue-axios
main.ts
import Vue from 'vue'
import App from './App.vue'
import './registerServiceWorker'
import router from './router'
import store from './store'
import axios from 'axios' //追記
import VueAxios from 'vue-axios' //追記

Vue.config.productionTip = false
Vue.use(VueAxios, axios) //追記

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')
About.vue
<template>
  <div class="about">
    <h1>This is an about page</h1>
    <button @click="clicked" >Call API</button>
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue, Emit } from 'vue-property-decorator';

@Component
export default class About extends Vue {
  private clicked():void {
      this.axios.get('https://httpbin.org/get')
        .then((response) => {
          console.log(response);
        })
        .catch((e) => {
          console.log(e);
        });
  }
}
</script>

consoleにデータが来てれば成功。

フロントエンドからexpressの内部APIを叩く

上のコードのURLをそのままhttp://x.x.x.x:3000とすると以下のCORSのエラーが出る。

Access to XMLHttpRequest at http://x.x.x.x:3000/ from origin http://x.x.x.x:8080 has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.

CORS(Cross-Origin Resource Sharing)とは何か?

あるオリジンで動いている Web アプリケーションに対して、別のオリジンのサーバーへのアクセスをオリジン間 HTTP リクエストによって許可できる仕組み

引用) https://qiita.com/att55/items/2154a8aad8bf1409db2b

どうしたらいいか

index.js(CORS設定版)
const express = require('express');
const bodyParser = require('body-parser');
const app = express();

// CORSを許可する
app.use(function(req, res, next) {
    res.header("Access-Control-Allow-Origin", "*");
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");

    // OPTIONSでメソッドがバレないようにする。 (?)
    if ('OPTIONS' === req.method) {
        res.send(200)
    } else {
        next()
    }
});

app.use(bodyParser.urlencoded({
    extended: true
}));
app.use(bodyParser.json());

// POST
app.post('/', function(req, res) {
    console.log(req.body);
    res.send('Hello');
})
// GET
app.get('/', (req, res) => res.send('Hello'));

app.listen(3000, () => console.log('Listening on port 3000'));

上記のコードにしてフロントとバックを起動後、GETでコールしてみる。

$ cd app
$ node index.js #バックエンド起動
$ cd front
$ npm run serve #フロントエンド起動

コンソールに以下が得られたら成功。

{data: "Hello", status: 200, statusText: "OK", headers: {}, config: {}, …}

Appendix

EC2インスタンスに置いたvueファイルを更新するのにいちいちscpとかviとかしてるのはだるすぎるのでVSCodeから直接SSHでいじるための方法。

VSCode拡張機能であるremote developmentを入れるて以下に設定ファイルを書いておく。

.ssh/config
Host 任意の接続名   //configには何個も接続先とキーとかの情報を書けるのでそれらを区別する名前。
  HostName x.x.x.x
  User ec2-user
  Port 22
  IdentityFile /Users/xxx/.ssh/hoge.pem

参考

6
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
6