Vue(Vuex, axios) + ExpressでRESTful APIに超入門する

Vue(Vuex, axios) + ExpressでRESTful APIに超入門する:

株式会社diffeasyでフロントエンドエンジニアをやっている山本(@s-kaoruko)です!

普段、バックエンドの方が用意してくれたデータをひたすら表示するお仕事をしていますが、APIリクエスト投げた向こう側の世界、のぞいてみたくなりませんか・・・!?

というわけで、超シンプルなRESTful APIをJavaScriptで実装して、データの流れを追っかけてみました��

言葉遣い、用語の使い間違いがあればそっと教えて下さいmm

この記事は diffeasy Advent Calendar 2018 15日目の記事です。

リポジトリ


前提

  • npm(6.4.1)
  • vue/cli(3.1.1)
  • Vue(2.5.17)
  • Vuex
  • axios
  • Express(4.16.0)
▼フォルダ構成

practice-express/ 
   ├ client/ 
   │      ├ package.json 
   │      └ ... 
   └ server/ 
          ├ package.json 
          └ ... 
client/配下にVueのソースを、server/配下にExpressのソースを置いていきます。


フロントエンドの構築


インストール

# vue/cliをインストールしていない場合 
npm install -g @vue/cli 
 
cd ~/workspace/practice-express 
vue create client 
 
# vue createが終了したら 
cd client 
npm insall 
npm install axios --save 
 
# 起動後、`http://localhost:8080/`にアクセス 
npm run serve 
 
Hello, Vue��


Storeを構成する

practice-express/ 
   ├ client/ 
   │      ├ package.json 
   │      ├ ... 
   │      ├ store/ 
   │      │     ├ modules/ 
   │      │     │       ├ test.js 
   │      │     │       └ ... 
   │      │     ├ index.js 
   │      │     └ mutation.js  
   │      └ ... 
 
今回はstore/index.jsにVuexのインスタンス定義をし、store/modules/配下にapiを投げるモジュールを書いていきます。

store/mutation.jsには定数を定義しています。(→ミューテーション・タイプに定数を使用する


リクエスト投げ投げモジュールを作成

client/store/modules/test.js
import axios from 'axios' 
const API_URI = 'http://localhost:3000' 
 
import { 
  TEST, TEST_FAILURE, TEST_SUCCESS 
} from '../mutation' 
 
export default { 
  state: { 
    test: null 
  }, 
  getters: { 
    test: state => { 
      return state.test 
    } 
  }, 
  actions: { 
    [TEST] (params = null) { 
      let data = {} 
      if (params) data = params.data 
      axios.get(API_URI + '/test', {data: data}) 
      .then(res => { 
        if (res.status === 200 || res.status === 304) { 
          if (res.data.error) { 
            this.commit(TEST_FAILURE, res.data) 
          } else { 
            this.commit(TEST_SUCCESS, {data: res.data, callback: params.callback}) 
          } 
        } 
      }) 
      .catch(error => { 
        throw error 
      }) 
    } 
  }, 
  mutations: { 
    [TEST_FAILURE] (state, data) { 
      console.log('TEST_FAILURE') 
    }, 
    [TEST_SUCCESS] (state, data) { 
      console.log('TEST_SUCCESS') 
      state.test = data.data.text 
      if (data.callback) { 
        data.callback(data.data) 
      } 
    } 
  } 
} 
これでthis.$store.dispatch('TEST')とコンポーネント内で呼ぶと、http://localhost:3000/testへgetリクエストが発生するようになりました!


バックエンドの構築


インストール

cd ~/workspace/practice-express 
 
mkdir app 
cd app 
 
npm init 
npm install express-generator -g 
 
# expressをviewエンジンなしでインストール 
express --no-view 
 
# 起動後、`http://localhost:3000/`にアクセス 
DEBUG=myapp:* npm start 
Hello, Express��


自動生成されたファイルを眺めてみる

practice-express/ 
   └ server/ 
          ├ ... 
          ├ package.json 
          ├ app.js 
          ├ bin/ 
          │   └ www 
          ├ public/ 
          └ routes/ 
              └ index.js 
bin

環境立ち上げ時に実行される処理を置くところ

public/

静的ファイルを置くところ
http://localhost:3000/はここのindexを表示するみたい

routes/

ルーティング処理を置くところ

クライアントからの要求に対しての処理群

app.js

メインファイル

共通する設定や処理はここに書く


APIを実装してみる

http://localhost:3000/testへGETリクエストが来たら、{"text":"success!"}を返すAPIを作ります。

まずは、ルーティングを作成。

app.js
var express = require('express'); 
var path = require('path'); 
var cookieParser = require('cookie-parser'); 
var logger = require('morgan'); 
 
var indexRouter = require('./routes/index'); 
var testRouter = require('./routes/test'); // ←追加 
 
var app = express(); 
 
app.use(logger('dev')); 
app.use(express.json()); 
app.use(express.urlencoded({ extended: false })); 
app.use(cookieParser()); 
app.use(express.static(path.join(__dirname, 'public'))); 
 
app.use('/', indexRouter); 
app.use('/test', testRouter); // ←追加 
 
module.exports = app; 
 
実際に処理をするファイルを作成

/routes/test.js
var express = require('express') 
var router = express.Router() 
 
router.get('/', function(req, res, next) { 
  const data = { 
    text: 'success!' 
  } 
  res.send(data) 
}) 
 
module.exports = router 
 
expressを再起動し、http://localhost:3000/testへアクセスしてみます。
{"text":"success!"}と表示されたら大成功��


VueからExpressにリクエストを投げ、レスポンスデータを表示する

フロントエンドとバックエンド、それぞれのピースはできたので、組み合わせてみます。

buttonをクリックするとtextareaにレスポンスデータが表示されるコンポーネントを作成しました。

<template> 
  <div> 
    <button type="button" @click="click">get</button> 
    <textarea v-model="test"></textarea> 
  </div> 
</template> 
 
<script> 
export default { 
  name: "HelloWorld", 
  computed: { 
    test () { 
      return this.$store.getters.test 
    } 
  }, 
  methods: { 
    click () { 
      this.$store.dispatch('TEST') 
    } 
  } 
}; 
</script> 


スクリーンショット 2018-12-15 17.37.14.png




スクリーンショット 2018-12-15 17.36.56.png


��


CORS(オリジン間リソース共有)

異なるドメインに対してアクセスを行ったとき、許可なくレスポンスデータを読み込むことができない仕組みです。

スキーム・ホスト・ポート番号で評価されます。

(→ https://developer.mozilla.org/ja/docs/Web/HTTP/CORS)

今回はhttp://localhost:8080http://localhost:3000でポートを分けて実装したので怒られたようです。

Express側で、http://localhost:8080からのレスポンスデータ読み込みを許可します。

/server/app.js
// CORSを許可する処理を追加 
app.use(function(req, res, next) { 
  res.header("Access-Control-Allow-Origin", "http://localhost:8080"); 
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept"); 
  next() 
}) 
 


スクリーンショット 2018-12-15 17.47.15.png


������


最後に

マークアップエンジニア出身なこともあり、JavaScript以外の言語に馴染みがないので、APIを作って学んでみるのにExpressはとてもいいなと思いました!(何をやってるか読解するのにストレスがあまりない)

今回はGETのみでしたが、次回はCRUD制覇したり、認証まわりの実装にチャレンジしたりしたいと思います!

Have a nice RESTful!

コメント

このブログの人気の投稿

投稿時間:2021-06-17 22:08:45 RSSフィード2021-06-17 22:00 分まとめ(2089件)

投稿時間:2021-06-20 02:06:12 RSSフィード2021-06-20 02:00 分まとめ(3871件)

投稿時間:2021-06-17 05:05:34 RSSフィード2021-06-17 05:00 分まとめ(1274件)