LoginSignup
3
5

More than 3 years have passed since last update.

Androidエンジニアが慣れている技術で作る維持費0円のサーバサイドアプリケーション

Last updated at Posted at 2020-08-22

今回紹介する技術スタックの紹介

普段Androidアプリを作っていますが、たまに認証周りなどでサーバサイドの技術検証をすることがあります。そのときよく使う技術スタックがこちらです。

Google App Engine スタンダード環境(Java8)

  • Javaサーブレッドをデプロイできます。
  • アクセスがなければ0円で維持できます。
    • 久しぶりのアクセスだとコールドスタートになり、レンスポンスに5秒くらいかかります。
  • アクセスがあっても1インスタンスで収まる少ないアクセス数ならば0円で維持できます。

無料の割り当てについての公式情報はこちら

ちなみにスタンダード環境の他にフレキシブル環境というものもありますが、そちらは0円で維持できません。

スタンダード環境とフレキシブル環境の違いについての公式情報はこちら

Ktor

KotlinとCoroutineでHTTPサーバが作れます。Androidの人が普段お世話になっているKotlin言語の記述力を活かしたフレームワークです。
所謂SinatraライクなWebフレームワークです。

Gradle

ビルドしてローカルサーバーを起動したり、Google App Engineにデプロイ出来ます。

参考文献

この記事で紹介している内容は、こちらの記事の内容が元になっています。
Run a Kotlin Ktor app on App Engine standard environment

前準備

参考文献Before you begin 節にある前準備を行います。

  • JDK8をインストールします。
  • Google Cloud SDKをインストールします。
  • Google Cloud Platform(GCP)のプロジェクトを作り、App Engineアプリケーションを作成します。
    • 公式解説
    • 次の「今回使用したgcloudコマンド」節も参考にしてください。
  • プロジェクトIDの名前を PROJECT_ID 環境変数に設定します。
  • 課金の有効化を行います。これをやらないとデプロイ出来ません。公式解説

今回使用したgcloudコマンド

tfandkusu-qiita-gae の部分は各自でグローバルでユニークな名前を設定します。

# GCPのプロジェクトを作る
gcloud projects create tfandkusu-qiita-gae
# App Engineアプリケーションを作成する
gcloud app create --project tfandkusu-qiita-gae

リージョンを聞かれます。特にこだわりがなければ近いところを選択します。asia-northeast1が東京です。

IntelliJ IDEA Community Editionをインストールする

もしあなたが普段Androidアプリを開発しているとしたら、Android Studioがインストールされていると思います。しかし今回はAndroidではない素のGradleプロジェクトを作ります。その機能はAndroid Studioに無いので、IntelliJ IDEA Community Editionをインストールします。

ダウンロードリンク

また、Android StudioとIntelliJ IDEAは共存できます。Android Studio 4.0.1とIntelliJ IDEA Community Edition 2020.1.4で確認しています。

IntelliJ IDEAでGradleプロジェクトを作成する

IntelliJ IDEA Community Editionを起動します。
Create New Project をクリックします。
GradleKotlin/JVMをチェックして Next ボタンをクリックします。

スクリーンショット 2020-08-22 23.34.43.png

プロジェクト名、ディレクトリなどを設定して、 Finish ボタンをクリックします。

スクリーンショット 2020-08-22 23.35.20.png

Ktorを使えるようにする。

Ktorライブラリを追加

このようにプロジェクトルートの build.gradle ファイルを編集します。

build.gradle
// 略
repositories {
    mavenCentral()
    // 追加
    jcenter()
}

dependencies {
    implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
    // 追加
    // ktorのバージョン
    def ktor_version = '1.4.0'
    // ローカルテストサーバ起動
    implementation "io.ktor:ktor-server-netty:$ktor_version"
    // サーブレットを作る
    implementation "io.ktor:ktor-server-servlet:$ktor_version"
    // HTMLをKotlinでレンダリングする
    implementation "io.ktor:ktor-html-builder:$ktor_version"
}
// 略

Hello Worldを作る

メインとなるKotlinファイルを置くパッケージを作成して、そこにKotlinファイルを作成します。

スクリーンショット 2020-08-23 0.08.35.png

Kotlinファイルの内容です。

Application.kt
package com.tfandkusu.qiitagae

import io.ktor.application.Application
import io.ktor.application.call
import io.ktor.html.respondHtml
import io.ktor.routing.get
import io.ktor.routing.routing
import kotlinx.html.body
import kotlinx.html.head
import kotlinx.html.p
import kotlinx.html.title

fun Application.main() {
    routing {
        get("/") {
            call.respondHtml {
                head {
                    title { +"Hello World" }
                }
                body {
                    p {
                        +"Hello World"
                    }
                }
            }
        }
    }
}

ローカルサーバを起動できるようにする

Gradleアプリケーションプラグインを設定する

build.gradleの最後にこちらを追加します。

build.gradle
apply plugin: 'application'
mainClassName = 'io.ktor.server.netty.EngineMain'

Ktorの設定ファイルを追加する

src/resources/application.conf を追加します。

src/resources/application.conf
ktor {
    deployment {
        // ローカルサーバ起動ポート番号
        port = 8080
    }
    application {
        // HelloWorldを作ったパッケージ名付きのKotlinソースコード名にKt.mainを付ける
        modules = [ com.tfandkusu.qiitagae.ApplicationKt.main ]
    }
}

ローカルサーバを起動する

前述の設定でこちらのコマンドでローカルサーバを起動できるようになりました。

./gradlew run

ブラウザで http://localhost:8080/ にアクセスすると、Hello Worldが表示されます。

エラーが出るようにする

このままだと、配列の領域外アクセス等の実行時エラーが発生しても標準出力にはなにも表示されず、デバッグ困難です。 

logback-classic ライブラリを追加する

logback-classic ライブラリを追加することで、標準出力にエラーが表示されるようになります。

build.gradle
// 略
dependencies {
    // 略
    // 追加
    // エラーが出るようにする
    implementation "ch.qos.logback:logback-classic:1.2.3"
}
// 略

エラーが標準出力に出ることを確認する

Application.kt
fun Application.main() {
    routing {
        get("/") {
            val a = mutableListOf<Int>()
            a[0] = 1
            // 略
        }
    }
}

./gradlew run を実行してブラウザで http://localhost:8080/ にアクセスすると、コンソールにスタックトレースが出ることを確認出来ます。

00:30:26.371 [nioEventLoopGroup-4-1] ERROR Application - Unhandled: GET - /
java.lang.IndexOutOfBoundsException: Index: 0, Size: 0
        at java.util.ArrayList.rangeCheck(ArrayList.java:657)
        at java.util.ArrayList.set(ArrayList.java:448)

Google App Engineにデプロイする

Google App Engine Gradle pluginを設定する

導入

Google App Engine Gradle pluginを使うと、1コマンドでビルドしてGoogle App Engineにデプロイすることが出来ます。

build.gradle
// 先頭に追加
buildscript {
    repositories {
        mavenCentral()
    }

    dependencies {
        classpath 'com.google.cloud.tools:appengine-gradle-plugin:2.3.0'
    }
}
// 元からある部分
plugins {
    id 'org.jetbrains.kotlin.jvm' version '1.3.72'
}
// 2つのプラグインを追加
apply plugin: 'war'
apply plugin: 'com.google.cloud.tools.appengine'

設定

バージョン名とGCPのプロジェクトIDはbuild.gradleで設定します。

build.gradle
// 最後に追加
// Google App Engineの設定
appengine {
    deploy {
        // バージョン名
        version = "a1"
        // GCPのプロジェクトID
        projectId = System.getenv()['PROJECT_ID']
    }
}

Google App EngineとJavaサーブレットの設定を行う

設定ファイルを置くディレクトリを作成する

src/main/webapp/WEB-INF ディレクトリを作成します。

スクリーンショット 2020-08-23 1.42.06.png

Google App Engineの設定ファイルを作成する

src/main/webapp/WEB-INF/appengine-web.xml
<?xml version="1.0" encoding="utf-8"?>
<appengine-web-app xmlns="http://appengine.google.com/ns/1.0">
    <threadsafe>true</threadsafe>
    <runtime>java8</runtime>
</appengine-web-app>

Javaサーブレットの設定ファイルを作成する

src/main/webapp/WEB-INF/web.xml
<?xml version="1.0" encoding="ISO-8859-1" ?>
<web-app>
    <servlet>
        <display-name>KtorServlet</display-name>
        <servlet-name>KtorServlet</servlet-name>
        <servlet-class>io.ktor.server.servlet.ServletApplicationEngine</servlet-class>
        <!-- path to application.conf file, required -->
        <init-param>
            <param-name>io.ktor.config</param-name>
            <param-value>application.conf</param-value>
        </init-param>
    </servlet>
    <servlet-mapping>
        <servlet-name>KtorServlet</servlet-name>
        <url-pattern>/</url-pattern>
    </servlet-mapping>
</web-app>

こちらの内容は参考文献で紹介されているこちらのXMLファイルです。

gradleでデプロイする

gradleのappengineDeployタスクでデプロイ出来ます。

./gradlew appengineDeploy

完了したら、こちらのコマンドでブラウザが開き、デプロイされたWebアプリケーションにアクセスすることが出来ます。 

# tfandkusu-qiita-gae の部分は各自で作成したGCPのプロジェクトIDにします。
gcloud app browse --project=tfandkusu-qiita-gae

これで解説は終了です。
あとは検証や作成したい内容に応じて、ライブラリやソースコードを追加していきます。

補足

Autoreload

ローカルサーバについてソースコードを変更したらすぐに反映させる方法があります。
Ktor + GradleでのAutoreload

全体ソースコード

Githubで公開しています。

3
5
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
3
5