[Rails API x Docker] Einfache Umgebungskonstruktion mit Shell- und Funktionsprüfung mit Flutter

Das Verfahren wird sorgfältig durchgeführt, damit auch Anfänger fortfahren können.

Dinge die zu tun sind

スクリーンショット 2020-09-13 13.42.28.png

Diejenigen, die nur die Shell zum Starten des API-Containers sehen möchten → [hier](https://qiita.com/drafts/942ad5fe5c13f70a19c5/edit#1-2-%E3%82%B7%E3%82%A7%E3%83%AB % E3% 81% A7railsapi% E3% 82% B3% E3% 83% B3% E3% 83% 86% E3% 83% 8A% E3% 83% 93% E3% 83% AB% E3% 83% 89) Derzeit sind auch Rails API-Quellcode und Flutter-Quellcode verfügbar. Es besteht die Möglichkeit von

Verfahren

Annahme

--Lassen Sie die Flutter-Anwendung in Android Studio ausführen

1. Bis der Docker-Container auf der API-Seite gestartet wird

Wir werden einen Docker-Container für die Rails-API erstellen.

Es ist jedoch ineffizient, Befehle von 1 einzugeben, sodass die Grundlagen in der Shell zusammengefasst werden.

1-1. Erstellen eines Verzeichnisses

Bereiten Sie ein Verzeichnis vor, indem Sie den Projektnamen auf "app_name" anwenden.

$ mkdir app_name  #Bereiten Sie ein Verzeichnis für API-Apps vor
$ cd app_name

1-2. In die Shell eingebauter Rails-API-Container

Unten finden Sie die Shell, die sogar den API-Container erstellt. (Referenzartikel)

** Shell zum Starten der Beispiel-API **

set_up_rails.sh


#!/bin/bash

#config setting#############
APP_NAME="app_name"            #← Sie können es jederzeit ändern (möglicherweise mit dem Verzeichnisnamen).
MYSQL_PASSWORD="password"      #← Bitte frei ändern
###########################

echo "docker pull ruby2.6.6"
docker pull ruby:2.6.6

echo "docker pull mysql:5.7"
docker pull mysql:5.7

echo "docker images"
docker images

echo "make Dockerfile"

cat <<EOF > Dockerfile
FROM ruby:2.6.6
ENV LANG C.UTF-8
RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs
#Garnaufbau
RUN curl -o- -L https://yarnpkg.com/install.sh | bash
ENV PATH /root/.yarn/bin:/root/.config/yarn/global/node_modules/.bin:\$PATH
#Arbeitsverzeichnis erstellen und einrichten
RUN mkdir /${APP_NAME}
ENV APP_ROOT /${APP_NAME}
WORKDIR \$APP_ROOT
#Hostseite (lokal) Gemfile hinzufügen
ADD ./Gemfile \$APP_ROOT/Gemfile
ADD ./Gemfile.lock \$APP_ROOT/Gemfile.lock
#Gemfile Bundle installieren
RUN bundle install
ADD . \$APP_ROOT
#Weil ein Fehler beim Deinstallieren der Schienen 6 des Edelsteinversionsgarns auftritt
RUN gem uninstall yarn -aIx
#Webpacker-Einstellungen
#RUN rails webpacker:install
EOF

echo "make Gemfile"
cat <<EOF > Gemfile
source 'https://rubygems.org'
git_source(:github) { |repo| "https://github.com/#{repo}.git" }
gem 'rails', '~> 6.0.3.2'
EOF

echo "make Gemfile.lock"
touch Gemfile.lock

echo "make docker-compose.yml"
cat <<EOF > docker-compose.yml
version: '3'
services:
  db:
    image: mysql:5.7
    environment:
      MYSQL_ROOT_PASSWORD: ${MYSQL_PASSWORD}
      MYSQL_DATABASE: root
    ports:
      - '3306:3306'
  api:
    build: .
    command: bundle exec rails s -p 3000 -b '0.0.0.0'
    volumes:
      - .:/${APP_NAME}
    ports:
      - '3000:3000'
    links:
      - db
EOF

echo "docker-compose run api rails new . --api --force --database=mysql --skip-bundle"
docker-compose run api rails new . --api --force --database=mysql --skip-bundle

echo "docker-compose run api bundle exec rails webpacker:install"
docker-compose run api bundle exec rails webpacker:install

docker-compose build

# fix config/database.yml
echo "fix config/database.yml"
cat config/database.yml | sed "s/password:$/password: ${MYSQL_PASSWORD}/" | sed "s/host: localhost/host: db/" > __tmpfile__
cat __tmpfile__ > config/database.yml
rm __tmpfile__

echo "docker-compose run api rails db:create"
docker-compose run api rails db:create

Erstellen Sie eine neue Datei direkt unter dem Projekt aus dem Editor und kopieren und fügen Sie ↑ ein und speichern Sie sie als set_up_rails.sh usw. Bitte bearbeiten Sie den app_name usw. mit der Aufschrift" Bitte frei ändern ".

Ändern Sie nach dem Speichern die Shell-Berechtigungen wie unten gezeigt und führen Sie sie aus (dies dauert ca. 5 Minuten).

$ chmod 755 set_up_rails.sh  #Berechtigungen ändern
$ ./set_up_rails.sh          #Führen Sie die Setup-Shell aus
docker pull ruby2.6.6
2.6.6: Pulling from library/ruby
57df1a1f1ad8: Pull complete
71e126169501: Pull complete
1af28a55c3f3: Pull complete
・
・
・

Überprüfen Sie nach dem Ausführen der Shell den Status des Containers mit "$ docker-compose ps". Es gibt kein Problem, wenn es wie folgt aussieht.

$ docker-compose ps
     Name             Command       State       Ports
----------------------------------------------------------
app_name_db_1     docker-           Up      0.0.0.0:3306->
                  entrypoint.sh             3306/tcp,
                  mysqld                    33060/tcp

1-3. Start und Bestätigung des Containers

Starten Sie als Nächstes den in der Shell erstellten Container.

$ docker-compose up
rails-api-handson_db_1 is up-to-date
Creating rails-api-handson_api_1 ... done
Attaching to rails-api-handson_db_1, rails-api-handson_api_1
db_1   | 2020-09-12 08:27:00+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.31-1debian10 started.
・
・
・
api_1  | * Environment: development
api_1  | * Listening on tcp://0.0.0.0:3000
api_1  | Use Ctrl-C to stop    #← Wenn das herauskommt, ist es OK!

Es werden viele Protokolle des Docker-Containers angezeigt. Wenn jedoch das letzte ** `Strg-C zum Stoppen verwenden ** ** angezeigt wird, wird der Container gestartet und ist in Ordnung.

Nachdem wir bestätigt haben, dass der Container gestartet wurde, greifen wir auf http: // localhost: 3000 zu und prüfen, ob eine Antwort als Rails ordnungsgemäß zurückgegeben wird. Wenn es wie folgt aussieht, ist der Betrieb des API-Containers in Ordnung.

スクリーンショット 2020-09-12 17.38.44.png

2. Rails API-Implementierung

Da es sich um eine Betriebsprüfung handelt, verwenden wir einfache Benutzerdaten. Diesmal,

User ( id, name, email )

Ich werde versuchen, es mit Ressourcen wie zu implementieren.

2-1. Erstellung des Benutzermodells und Vorbereitung der DB-Tabelle

Bereiten Sie das Benutzermodell und die Tabelle vor.

Nur hier werde ich separat vorstellen ** Verwendung der Migration ** und ** Verwendung von Ridgepole ** (beide spiegeln das gleiche Modell und Schema als Ergebnis wider).

Ridgepole ist ein Tool, mit dem Sie Ihr Schema ohne Migration verwalten können. Ich werde hier fortfahren, aber wenn Sie ein regelmäßiger Benutzer der Migration sind, gibt es kein Problem.

Muster 1) Erstellen Sie ein Modell und eine Tabelle durch Migration

Geben Sie den Container ein und erstellen Sie mit dem Generator ein Benutzermodell.

$ docker-compose exec api bash     #Betritt den Container
# rails g model user name:string email:string
#↑ Wenn Sie nicht können, versuchen Sie es über Bundle (# bundle exec Rails)....Mögen)
# exit                             #Verlassen des Containers (danach wird das Betreten und Verlassen des Containers nicht mehr angegeben.
                                   #Befehlszeile "$"Und" # "zu unterscheiden. )
$

Sie müssen lediglich migrieren.

# rake db:migrate

Muster 2) Erstellen Sie Modell & Tabelle mit Ridgepole

Erstellen Sie ein Modell, indem Sie die Migration überspringen.

# rails g model user --skip-migration

Fügen Sie "gem'ridgepole", "> = 0.8.0" zum Gemfile direkt unter dem Projekt hinzu. Unter mysql2 sollte es kein Problem geben.

Gemfile


gem 'mysql2', '>= 0.4.4'     #Ursprünglich
gem 'ridgepole', '>= 0.8.0'  #Füge das hinzu

Installiere den hinzugefügten Edelstein.

# bundle install

Erstellen Sie als Nächstes eine Datei mit dem Namen "Schemafile.rb" in "db /" (Ridgepole verwaltet das Schema hier zentral).

Schreiben Sie Folgendes in db / Schemafile.rb und speichern Sie es.

db/Schemafile.rb


create_table "users", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t|
  t.string "name"
  t.string "email"
  t.timestamps
end

Reflektieren Sie die Schemadatei mit dem Befehl ridgepole.

# bundle exec ridgepole --config ./config/database.yml --file ./db/Schemafile.rb --apply
Apply `./db/Schemafile.rb`
-- create_table("users", {:options=>"ENGINE=InnoDB DEFAULT CHARSET=utf8"})
   -> 0.0716s

2-2. Erstellung des Benutzercontrollers

Lesen Sie diesen Artikel und fügen Sie die Hauptversion der API (1 Teil für v1.3) in die URI ein. In diesem Artikel wird jedoch der Namespace "api" für den URI verwendet.

Dies ist meine persönliche Meinung, aber ich werde sie unter der Annahme implementieren, dass sie durch eine Subdomain usw. angezeigt wird, anstatt "api" in der URI anzugeben.

example.com/api/vi/users  #API in URI anzeigen
api.example.com/vi/users  #Wird von der Subdomain angezeigt

Kehren wir nun zum Hauptthema der Controller-Erstellung zurück.

Erstellen Sie vor dem Controller ein v1 /, das die Hauptversion angibt, und erstellen Sie darin einen Benutzer-Controller.

$ mkdir app/controllers/v1
$ rails g controller v1::users

Der Inhalt der Controller-Datei lautet wie folgt.

*/v1/users_controller.rb


class V1::UsersController < ApplicationController
  before_action :set_user, only: [:show, :update, :destroy]

  def index
    users = User.order(created_at: :desc)
    render json: { status: 'SUCCESS', message: 'Loaded user', data: users }
  end

  def show
    render json: { status: 'SUCCESS', message: 'Loaded the user', data: @user }
  end

  def create
    user = User.new(user_params)
    if user.save
      render json: { status: 'SUCCESS', data: user }
    else
      render json: { status: 'ERROR', data: user.errors }
    end
  end

  def destroy
    @user.destroy
    render json: { status: 'SUCCESS', message: 'Deleted the user', data: @user }
  end

  def update
    if @user.update(user_params)
      render json: { status: 'SUCCESS', message: 'Updated the user', data: @user }
    else
      render json: { status: 'SUCCESS', message: 'Not updated', data: @user.errors }
    end
  end

  private

  def set_user
    @user = User.find(params[:id])
  end

  def user_params
    params.require(:user).permit(:name, :email)
  end
end

2-3 Routing-Einstellungen

Machen Sie config / route.rb wie folgt.

config/routes.rb


Rails.application.routes.draw do
  namespace 'v1' do
    resources :users
  end
end

Nach ↑ sollten Sie in der Lage sein, das Routing mit dem Befehl "Rechenrouten" zu überprüfen. Es ist in Ordnung, wenn das folgende Routing angezeigt wird.

# rake routes
  Prefix Verb    URI Pattern               Controller#Action
v1_users GET     /v1/users(.:format)       v1/users#index
         POST    /v1/users(.:format)       v1/users#create
 v1_user GET     /v1/users/:id(.:format)   v1/users#show
         PATCH   /v1/users/:id(.:format)   v1/users#update
         PUT     /v1/users/:id(.:format)   v1/users#update
         DELETE  /v1/users/:id(.:format)   v1/users#destroy

3. Überprüfen Sie den Betrieb der API mit Postman

Postman ist einer der Web-API-Testclientdienste. Verwenden Sie diese Option, um den Betrieb der API zu überprüfen.

3-1. Postboteninstallation

Installieren Sie Postman auf der offiziellen Website (https://www.postman.com/). Ich habe es schon einmal installiert, daher erinnere ich mich nicht an viel, aber ich denke, es war in Ordnung, wenn ich mich registriert und fortgefahren habe ...

Bereiten Sie nach der Installation von Postman zunächst einen Benutzerdatensatz auf der Konsole vor. Ich denke, das folgende Gefühl ist in Ordnung.

# rails c
Loading development environment (Rails 6.0.3.3)
irb(main):001:0> User.create(name: "hoge", email: "[email protected]")

3-2. Holen Sie sich die DB-Benutzerressource mit GET

Geben Sie in Postman die "GET-Methode" und den "URI" wie unten gezeigt an und klicken Sie auf die Schaltfläche "Senden".

Anschließend können Sie den Hauptteil der Antwort überprüfen, die vom Hauptteil am unteren Bildschirmrand zurückgegeben wird. Wenn Sie dies bisher tun können, ist es ein Erfolg, die Funktionsweise der API zu überprüfen!

スクリーンショット 2020-09-12 21.15.09.png

3-3. DB-Benutzerressource mit POST hinzufügen

Geben Sie nun die POST-Methode an und fügen Sie die Daten wie unten gezeigt in den Anforderungshauptteil ein. Stellen Sie zu diesem Zeitpunkt sicher, dass das Format "JSON" ist (wobei "JSON" im Bild orange ist).

Bei Erfolg können Sie den registrierten Benutzerdatensatz im Antworttext überprüfen.

スクリーンショット 2020-09-12 21.21.14.png

Wenn Sie erneut versuchen, mit der GET-Methode darauf zuzugreifen, können Sie den von der POST-Methode hinzugefügten Datensatz auch sehen.

スクリーンショット 2020-09-12 21.22.33.png

4. Drücken Sie die API mit Flutter

Das Ergebnis sieht so aus

Da es sich um eine Funktionsprüfung handelt, fühlt es sich wie ein Minimum an.

スクリーンショット 2020-09-12 23.28.18.png

4-1. Projekterstellung

Erstellen Sie ein Flutter-Projekt aus ** Datei> Neu> Neues Flutter-Projekt ... **. Es ist in Ordnung, wenn der iPhone- oder Android-Simulator (Emulator) gestartet werden kann.

4-2. Aktivieren Sie die HTTP-Kommunikation

Wenn dies die Standardeinstellung ist, tritt beim Importieren eines Pakets, das http ausführt, ein Fehler auf, sodass ein kleiner Vorgang erforderlich ist.

Fügen Sie zunächst Folgendes zu Abhängigkeiten hinzu: von pubspec.yaml.

pubspec.yaml


# ~Kürzung~
dependencies:
  http: ^0.12.0   #← Hinzufügen
  flutter:
    sdk: flutter
# ~Kürzung~

Anschließend wird der folgende Flutter-Befehl oben im Android Studio-Editor angezeigt. Wählen Sie dieses Mal ** Pub get **.

Wenn Sie in der zukünftigen Arbeit einen Fehler in Bezug auf HTTP erhalten, sollten Sie sich auch den diesen Artikel ansehen, auf den ich verwiesen habe. Ich weiß es nicht.

スクリーンショット 2020-09-12 22.35.18.png

4-3 Bearbeiten Sie main.dart

Wenn Sie nur den Vorgang überprüfen möchten, schreiben Sie "lib / main.dart" wie folgt neu und es wird funktionieren.

Da Flutter eine rudimentäre Grundschule ist, kommentieren Sie bitte, wenn Sie Vorschläge haben.

lib/main.dart


import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

void main() => runApp(MyApp());

class MyApp extends StatefulWidget {
  MyApp({Key key}) : super(key: key);

  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  Future<GetResults> res;
  @override
  void initState() {
    super.initState();
    res = getUsers();
  }

  // postUser()Benutzer registrieren bei. Holen Sie sich die Benutzerliste erneut in setState
  void _postUser() {
    postUser();
    setState(() {
      res = getUsers();
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Rufen Sie die API mit POST auf und übergeben Sie die JSON-Parameter',
      theme: ThemeData(
        primarySwatch: Colors.yellow,
      ),
      home: Scaffold(
        appBar: AppBar(
          title: Text('RailsAPI x Flutter'),
        ),
        body: Center(
          child: FutureBuilder<GetResults>(
            future: getUsers(),
            builder: (context, snapshot) {
              if (snapshot.hasData) {
                return Text(
                    snapshot.data.message.toString()
                );
              } else if (snapshot.hasError) {
                return Text("${snapshot.error}");
              }
              return CircularProgressIndicator();
            },
          ),
        ),
        floatingActionButton: FloatingActionButton(
          onPressed: _postUser,
          tooltip: 'Increment',
          child: Icon(Icons.add),
        ),
      ),
    );
  }
}

class GetResults {
  final String message;
  GetResults({
    this.message,
  });
  factory GetResults.fromJson(Map<String, dynamic> json) {
    var datas = '';
    json['data'].forEach((item) => datas += 'id: ' + item['id'].toString() + ', name: ' + item['name'] + ', email: ' + item['email'] + '\n');
    return GetResults(
      message: datas,
    );
  }
}

class PostResults {
  final String message;
  PostResults({
    this.message,
  });
  factory PostResults.fromJson(Map<String, dynamic> json) {
    return PostResults(
      message: json['message'],
    );
  }
}

class SampleRequest {
  final String name;
  final String email;
  SampleRequest({
    this.name,
    this.email,
  });
  Map<String, dynamic> toJson() => {
    'name': name,
    'email': email,
  };
}

Future<GetResults> getUsers() async {
  var url = 'http://127.0.0.1:3000/v1/users';
  final response = await http.get(url);
  if (response.statusCode == 200) {
    return GetResults.fromJson(json.decode(response.body));
  } else {
    throw Exception('Failed');
  }
}

Future<PostResults> postUser() async {
  var url = "http://127.0.0.1:3000/v1/users";                             //API-URI
  var request = new SampleRequest(name: 'foo', email: '[email protected]'); //Benutzerparameter. Sie können es frei ändern
  final response = await http.post(url,
      body: json.encode(request.toJson()),
      headers: {"Content-Type": "application/json"});
  if (response.statusCode == 200) {
    return PostResults.fromJson(json.decode(response.body));
  } else {
    throw Exception('Failed');
  }
}

Wenn Sie den Simulator starten, wird der registrierte Benutzer ordnungsgemäß zurückgegeben!

スクリーンショット 2020-09-12 21.30.54.png

Wenn Sie unten rechts auf die Schaltfläche Hinzufügen klicken, können Sie sehen, dass die in main.dart angegebenen Benutzerdaten registriert und erfasst wurden!

スクリーンショット 2020-09-12 21.58.37.png

das Ende

Wenn Sie Fragen oder Anregungen haben, hinterlassen Sie bitte einen Kommentar.

Recommended Posts

[Rails API x Docker] Einfache Umgebungskonstruktion mit Shell- und Funktionsprüfung mit Flutter
[Docker] Rails 5.2-Umgebungskonstruktion mit Docker
Build Rails (API) x MySQL x Nuxt.js Umgebung mit Docker
[Umgebungskonstruktion mit Docker] Rails 6 & MySQL 8
Schienenumgebungskonstruktion mit Docker (persönliche Apokalypse)
Erstellen Sie mit Docker eine TensorFlow-Betriebsüberprüfungsumgebung
Konstruktionsverfahren für die Docker-Umgebung "Rails 6 x MySQL 8" für die gemeinsame Nutzung mit Teams
Aufbau der Rails Docker-Umgebung
Erstellen Sie eine Entwicklungsumgebung für Rails-Anwendungen mit Docker [Docker, Rails, Puma, Nginx, MySQL]
Konstruktionsverfahren für Rails on Docker-Umgebungen
Erstellen einer Entwicklungsumgebung für Ruby on Rails mit Docker + VSCode (Remote Container)
Aufbau einer GPU-Umgebung mit Docker [Version Oktober 2020]
Erstellen einer Rails 6- und PostgreSQL-Umgebung mit Docker
Aufbau einer Laravel-Entwicklungsumgebung mit Docker (Mac)
[Docker] Entwicklung der Entwicklungsumgebung Rails6 / Ruby2.7 / MySQL8
Erstellen einer Umgebung für Laravel + MySQL + phpMyadmin mit Docker
CentOS8.2 (x86_64) + ruby2.5 + Rails5.2 + MariaDB (10.3.17) Umgebungskonstruktion
So erstellen Sie eine Rails 6-Umgebung mit Docker
So erstellen Sie eine Ruby on Rails-Entwicklungsumgebung mit Docker (Rails 6.x)
Erstellen Sie eine Bulletin-Board-API mit Zertifizierung und Autorisierung mit Rails 6 # 1 Environment Construction
So erstellen Sie eine Ruby on Rails-Entwicklungsumgebung mit Docker (Rails 5.x)
Ich habe versucht, eine Anwendung für maschinelles Lernen mit Dash (+ Docker) Teil 1 ~ Umgebungskonstruktion und Funktionsprüfung ~ zu erstellen
Einführung in Rspec mit Ruby on Rails x Docker
[Rails] So erstellen Sie eine Umgebung mit Docker
Konstruktions- und Entwicklungsverfahren für lokale WordPress-Umgebungen mit Docker
Mit Rails + Docker einfach Hallo Welt anzuzeigen
Konstruktionshandbuch für eine stabile Entwicklungsumgebung für "Rails6" mit "Docker-compose"
Erstellen Sie mit Docker x Cypress eine E2E-Testumgebung
Rails5 + MySQL8.0 + Top-Level-Volume-Umgebungskonstruktion mit Docker-Compose
Erstellen einer Datenbankumgebung mit Docker in Spring Boot (IntellJ)
[Flattern] Ubuntu 20.04 Umgebungskonstruktion
Docker x Rails 6 (Memo)
Ich habe eine Entwicklungsumgebung mit Rails6 + Docker + PostgreSQL + Materialise erstellt.
Erstellen Sie mit Docker eine Umgebung für Rails5 und postgresql, damit auch pgadmin verwendet werden kann
Aufbau der Rails6-Entwicklungsumgebung [Mac]
Rails Engineer Environment Construction Ruby2.7.1
Schienen Umgebungsbau Schienen5.2.1 ruby2.5.1 Catalina
Konstruktionsnotiz für die MySQL 5.7 (Docker) -Umgebung
Führen Sie Rails immer im Docker aus
Redmine (Docker) Umgebungskonstruktionsnotiz
Erstellen einer Docker-Umgebung mit WSL
Aufbau der Docker x Spring Boot-Umgebung
[Super einfach] Ruby-Umgebungskonstruktion
[Rails / MySQL] Aufbau einer Mac-Umgebung