うしろのこの本ください

なんでもかきます

開発者向けのミリシタAPIエンドポイント 「Princess」を Nuxt.js で使う

どうも

アイマスAPI と言えば im@study の im@sparql 辺りがあるが、ミリシタオンリーであれば REST で使えるエンドポイントがある。

api.matsurihi.me

特定のエンドポイントへリクエストを送ると対応した json データが返って来る。見た感じ個人運営の有志サービスなので、使う時は加減するか要相談案件。(こういうのにお金落とすべきだよなと思ったり)

せっかくだから軽く実践してみる。楽したいので慣れてる Nuxt.js と axios モジュールのみで。いつも通り create-nuxt-app から axios モジュールを使う設定、UI は element-ui でプロジェクト作成。

今回利用するエンドポイントはカードIDからカード情報を取れるもの。こんな感じでアクセスする。

const data = await this.$axios.$get(`https://api.matsurihi.me/mltd/v1/cards/100`)

axios の接続先は nuxt.config.js に baseURL として書いておけるので、v1 までをデフォルトとして設定する。

  axios: {
    // See https://github.com/nuxt-community/axios-module#options
    baseURL:'https://api.matsurihi.me/mltd/v1'
  }

こうする事でさっきの axios の記述はこう書ける

const data = await this.$axios.$get(`/cards/100`)

でどういう風に作るかというと、テキストボックスにカードID入力してボタン押したら画面に json の中身が出る、くらいでとりあえずはいいと思う。

適当に表示場所とボタンのコンポーネント用意、api 叩くのは Vuex の中で行う。コンポーネントはメインページで読み込んで使う。 まあオーソドックスな Nuxt の構成でおk。

components/Card.vue

<template>
  <section>
    <el-card v-for="card in cardData" :key="card.id">
      {{ card }}
    </el-card>
  </section>
</template>

<script>
import { mapGetters } from 'vuex'

export default {
  computed: {
    ...mapGetters(['cardData'])
  }
}
</script>

components/CardFetchButton.vue

<template>
  <section>
    <el-button type="primary" @click="fetchCardAsync">取得</el-button>
  </section>
</template>

<script>
import  { mapActions } from 'vuex'

export default {
  props: {
    cardId : String
  },
  methods: {
    ...mapActions(['fetchCard']),
    async fetchCardAsync() {
      try {
        await this.fetchCard(this.cardId)
        this.$notify({
          title: '成功',
          message: 'カード情報を更新しました',
          position: 'buttom-right',
          duration: '3000'
        })
      } catch (e) {
        this.$notify.error({
          title: '失敗',
          message: `${e}`,
          position: 'buttom-right',
          duration: '3000'
        })
      }
    }
  }
}
</script>

pages/index.vue

<template>
  <section class="container">
    <div>
      <Card />
      <el-input v-model="cardId" placeholder="カードIDを入力..." style="padding-top: 10px; width: 160px;"></el-input>
      <Button style="padding-top: 10px;" :cardId="cardId" />
    </div>
  </section>
</template>

<script>
import Card from '~/components/Card.vue'
import Button from '~/components/CardFetchButton.vue'

export default {
  data(){
    return {
      cardId : ''
    }
  },
  components: {
    Card,
    Button
  }
}
</script>

<style>

.container {
  min-height: 100vh;
  display: flex;
  justify-content: center;
  align-items: center;
  text-align: center;
}
</style>

store/index.js

export const state = () => ({
  cardData : []
})

export const getters = {
  cardData: (state) => state.cardData
}

export const mutations = {
  setCardData(state, { data }) {
    state.cardData = data
  }
}

export const actions = {
  async fetchCard({ commit }, id ) {
    const data = await this.$axios.$get(`/cards/${id}`)
    if (!data) throw new Error('Invalid card data')
    commit('setCardData', { data })
  }
}

作ってる途中でヘッダー欲しくなって作っちゃったけど別にいらない。

実際にコールしてみる。

f:id:apple19940820:20181111141611p:plain

f:id:apple19940820:20181111141638p:plain

いい感じ。IDを指定しない場合全件取れてくる。負荷高そう。

今回作った奴

github.com

感想

こういうサービスは続けていくの大変だし出来る範囲で応援したい。アマギフで支援できるので余力がある人はぜひ。

おわり