1
0

More than 1 year has passed since last update.

RailsとVue.js3のSPAアプリにDeepL apiを導入する

Posted at

ポートフォリオ作りの過程でRails×Vue.js3のSPAアプリにDeepL apiを導入したので過程を初学者視点で紹介します。
開発環境にはdockerを使用しています。

#version
Ruby 3.0.2
Rails 6.0.4
Vue.js3

#開発環境
Docker
docker-compose

APIで実現したいこと

スクリーンショット 2022-01-27 20.19.54.png

上記の画像の「AI翻訳の結果を表示する」ボタンを押すと上部に表示された日本語文を英訳して表示する。

DeepL apiの登録

こちらから登録します。
50,000文字/1ヶ月の制約はありますが無料プランもあります。

登録すると自身のアカウントに認証キーが表示されるのでそれをコピーしておきます。

Rails側の実装

gem httpclient 

上記gemをインストールします。DeepL apiは"https://api-free.deepl.com/v2/translate" というurlにget(もしくはpost)リクエストを認証キー、翻訳したいテキスト、変換結果の言語の3点をパラメーターとして含んだ上で送信する必要があります。httpclientはrailsのcontrollerからそのリクエストを送信するための記述を提供してくれるgemになります。

$ docker-compose build --no-cache

今回はdockerを使用しているので上記コマンドでgemをインストールします。

$ rails g controller api/translations

apiを叩くためのコントローラーを用意します。既存のコントローラーを使用しても問題ありません。

$ EDITOR="vi" bin/rails credentials:edit

deepl_api: 
    api_key: DeepL apiの認証キーを貼り付け

認証キーを直打ちしなくて済むようにcredentials.ymlに秘匿します。

translations_controller.rb

class Api::TranslationsController < ApplicationController
  require 'httpclient' #httpclientを使用できるようにします

  def translate
    @question = Question.find(params[:id])
    api_key = Rails.application.credentials.deepl[:api_key]
    uri = "https://api-free.deepl.com/v2/translate"
    client = HTTPClient.new
    params = {
      auth_key: api_key,
      text: @question.content,
      target_lang: "EN"
    }
    @response = client.get(uri, query: params)
    render json: @response.body
  end
end

前述の「実現したいこと」の画像に表示されている翻訳したい文章はQuestio モデルのcontentカラムに保存されているものになるのでparamsのtextには@question.contentを代入しています。

routes.rb

namespace :api, format: 'json' do
  get '/translate/:id', to: 'translations#translate'
end

questionモデルのidをパラメーターとして送信するため/:idを付け加えていますが'/translate'の部分は自由に書き換えてください(例えば'/aaa/:id'でも'translations#translate'によってapi/translations_controllerのtranslateアクションを実行してくれます)。

Vue側の実装

<template>
      <button @click="translateWithDeepL">
          AI翻訳の結果を確認する
      </button>
      <h1>翻訳結果: {{result}}</h1>
</template>

<script>
methods: {
  translateWithDeepL: function() {
     const question_id = this.question.id
     axios.get('/api/translate/'+ question_id)
     .then(response => {
     this.result = response.data.translations[0].text
    })
  }
}
</script>

axios.get('/api/translate/' + question_id)でroute.rbに設定したget '/translate/:id'にアクセスし、translations_controllerのtranslateアクションを実行という流れになります。

具体的には仮に翻訳したいテキストが[hello]で翻訳結果の言語を日本語に設定すると
https://api-free.deepl.com/v2/translate?auth_key=認証キー&text=hello&target_lang=JA
というURLにgetリクエストが送信され、

{
    "translations": [{
        "detected_source_language":"JA",
        "text":"こんにちは"
    }]
}

というresponseがjson形式でかえってきます。
このレスポンスのtextの部分だけ表示したいので

response.data.translations[0].text

という形でフロントエンド上では受け取っているわけです。

1
0
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
1
0