La procédure est soigneusement effectuée afin que même les débutants puissent continuer.

Ceux qui veulent voir uniquement le shell pour démarrer le conteneur API → [ici](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) Pour le moment, Rails API source code et Flutter source code sont également disponibles (* déconner) Il y a une possibilité de
GET
--Ajouter une ressource utilisateur de base de données avec POST$ docker-compose -v fonctionne)Nous allons créer un conteneur Docker pour l'API Rails.
Cependant, il est inefficace de taper des commandes à partir de 1, les bases sont donc résumées dans le shell.
Préparez un répertoire en appliquant le nom du projet à app_name.
$ mkdir app_name  #Préparer un répertoire pour mettre les applications API
$ cd app_name
Vous trouverez ci-dessous le shell qui construit même le conteneur d'API. (Article de référence)
set_up_rails.sh
#!/bin/bash
#config setting#############
APP_NAME="app_name"            #← N'hésitez pas à le changer (peut-être avec le nom du répertoire)
MYSQL_PASSWORD="password"      #← Veuillez changer librement
###########################
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
#configuration du fil
RUN curl -o- -L https://yarnpkg.com/install.sh | bash
ENV PATH /root/.yarn/bin:/root/.config/yarn/global/node_modules/.bin:\$PATH
#Créer et définir un répertoire de travail
RUN mkdir /${APP_NAME}
ENV APP_ROOT /${APP_NAME}
WORKDIR \$APP_ROOT
#Ajouter Gemfile côté hôte (local)
ADD ./Gemfile \$APP_ROOT/Gemfile
ADD ./Gemfile.lock \$APP_ROOT/Gemfile.lock
#Installation du bundle Gemfile
RUN bundle install
ADD . \$APP_ROOT
#Parce qu'une erreur se produit lors de la désinstallation des rails 6 de la version gem
RUN gem uninstall yarn -aIx
#paramètres Webpacker
#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
Créez un nouveau fichier directement sous le projet depuis l'éditeur & copiez et collez ↑ et enregistrez-le sous set_up_rails.sh etc. Veuillez éditer le app_name etc. qui dit" Veuillez changer librement ".
Après l'enregistrement, modifiez les autorisations du shell comme indiqué ci-dessous et exécutez-le (cela prend environ 5 minutes).
$ chmod 755 set_up_rails.sh  #Modifier les autorisations
$ ./set_up_rails.sh          #Exécuter le shell de configuration
docker pull ruby2.6.6
2.6.6: Pulling from library/ruby
57df1a1f1ad8: Pull complete
71e126169501: Pull complete
1af28a55c3f3: Pull complete
・
・
・
Après avoir exécuté le shell, vérifiez l'état du conteneur avec $ docker-compose ps. Il n'y a pas de problème si cela ressemble à ce qui suit.
$ 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
Ensuite, démarrez le conteneur construit dans le shell.
$ 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    #← Si cela sort, c'est OK!
Il y aura beaucoup de journaux pour le conteneur Docker, mais si le dernier ** Utiliser Ctrl-C pour arrêter ** apparaît, le conteneur est en cours d'exécution et c'est OK.
Maintenant que nous avons confirmé que le conteneur a démarré, accédons à http: // localhost: 3000 et voyons s'il renvoie correctement une réponse en tant que Rails. Si cela ressemble à ce qui suit, le fonctionnement du conteneur API est correct.

Comme il s'agit de la vérification des opérations, utilisons des données utilisateur simples. Cette fois,
User ( id, name, email )
Je vais essayer de le mettre en œuvre avec des ressources comme.
Préparez le modèle et la table utilisateur.
Seulement ici, je présenterai séparément ** Comment utiliser la migration ** et ** Comment utiliser Ridgepole ** (les deux refléteront le même modèle et schéma en conséquence).
Ridgepole est un outil qui vous permet de gérer votre schéma sans utiliser la migration. Je vais procéder ici, mais si vous êtes un utilisateur régulier de la migration, il n'y a pas de problème.
Entrez dans le conteneur et créez un modèle utilisateur avec le générateur.
$ docker-compose exec api bash     #Entrez dans le conteneur
# rails g model user name:string email:string
#↑ Si vous ne pouvez pas, essayez-le via Bundle (# bundle exec rails)....Comme)
# exit                             #Sortie du conteneur (après cela, entrer et sortir du conteneur n'est pas spécifié.
                                   #Ligne de commande "$"Et" # "pour distinguer. )
$
Tout ce que vous avez à faire est de migrer.
# rake db:migrate
Créez un modèle en ignorant la migration.
# rails g model user --skip-migration
Ajoutez gem'ridgepole ','> = 0.8.0' au Gemfile directement sous le projet. Il ne devrait y avoir aucun problème sous mysql2.
Gemfile
gem 'mysql2', '>= 0.4.4'     #À l'origine
gem 'ridgepole', '>= 0.8.0'  #Ajoute ça
Installez la gemme ajoutée.
# bundle install
Ensuite, créez un fichier appelé Schemafile.rb dans db / (Ridgepole gère le schéma de manière centralisée ici).
Écrivez ce qui suit dans db / Schemafile.rb et enregistrez-le.
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
Reflétez le fichier de schéma avec la commande 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
Reportez-vous à cet article et incluez la version principale de l'API (1 partie pour la v1.3) dans l'URI. Cependant, cet article utilise l'espace de noms api pour l'URI.
Ceci est mon opinion personnelle, mais je vais l'implémenter en supposant qu'il sera indiqué par un sous-domaine, etc. au lieu de spécifier api dans l'URI.
example.com/api/vi/users  #Afficher l'API dans l'URI
api.example.com/vi/users  #Montré par sous-domaine
Maintenant, revenons au sujet principal de la création de contrôleurs.
Avant le contrôleur, créez un v1 / indiquant la version principale, et créez-y un contrôleur d'utilisateurs.
$ mkdir app/controllers/v1
$ rails g controller v1::users
Le contenu du fichier du contrôleur est le suivant.
*/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
Créez config / routes.rb comme suit.
config/routes.rb
Rails.application.routes.draw do
  namespace 'v1' do
    resources :users
  end
end
Après ↑, vous devriez pouvoir vérifier le routage avec la commande rake routes. C'est OK si le routage suivant est reflété.
# 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
Postman est l'un des services client de test de l'API Web. Utilisez ceci pour vérifier le fonctionnement de l'API.
Installez Postman sur le site officiel (https://www.postman.com/). Je l'ai installé avant, donc je ne me souviens pas beaucoup, mais je pense que c'était OK si je me suis enregistré et que je continuais ...
Après avoir installé Postman, préparez d'abord un enregistrement utilisateur sur la console. Je pense que la sensation suivante est bonne.
# rails c
Loading development environment (Rails 6.0.3.3)
irb(main):001:0> User.create(name: "hoge", email: "[email protected]")
GETDans Postman, spécifiez la méthode GET et URI comme indiqué ci-dessous, puis appuyez sur le bouton Envoyer.
Ensuite, vous pouvez vérifier le corps de la réponse renvoyée par le corps en bas de l'écran. Si vous pouvez le faire jusqu'à présent, c'est un succès de vérifier le fonctionnement de l'API!

POSTSpécifions maintenant la méthode POST et incluons les données dans le corps de la requête comme indiqué ci-dessous. À ce stade, assurez-vous que le format est JSON (où" JSON "dans l'image est orange).
En cas de succès, vous pouvez vérifier l'enregistrement utilisateur enregistré dans le corps de la réponse.

Si vous essayez à nouveau d'accéder avec la méthode GET, vous pouvez également voir l'enregistrement ajouté par la méthode POST.

--Afficher les données utilisateur dans la base de données lors du lancement de l'application
Ajouter en bas à droitePuisqu'il s'agit d'un contrôle de fonctionnement, cela semble être un minimum.

Créez un projet Flutter à partir de ** Fichier> Nouveau> Nouveau projet Flutter ... **. C'est OK si le simulateur iPhone ou Android (émulateur) peut être démarré.
Si c'est la valeur par défaut, une erreur se produira lors de l'importation d'un package qui exécute http, donc une petite opération est nécessaire.
Tout d'abord, ajoutez ce qui suit à dependencies: of pubspec.yaml.
pubspec.yaml
# ~réduction~
dependencies:
  http: ^0.12.0   #← Ajouter
  flutter:
    sdk: flutter
# ~réduction~
Ensuite, la commande Flutter suivante apparaîtra en haut de l'éditeur Android Studio. Cette fois, sélectionnez ** Pub get **.
Si vous obtenez une erreur autour de Http dans les travaux futurs, vous pouvez également consulter le cet article auquel j'ai fait référence. Je ne sais pas.

Si vous voulez juste vérifier l'opération, réécrivez lib / main.dart comme suit et cela fonctionnera.
De plus, puisque Flutter est une école élémentaire rudimentaire, veuillez commenter si vous avez des suggestions.
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()Enregistrez l'utilisateur avec. Récupérez à nouveau la liste des utilisateurs dans setState
  void _postUser() {
    postUser();
    setState(() {
      res = getUsers();
    });
  }
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Appeler l'API avec POST et transmettre les paramètres JSON',
      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";                             //URI de l'API
  var request = new SampleRequest(name: 'foo', email: '[email protected]'); //Paramètres utilisateur. Vous pouvez le changer librement
  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');
  }
}
Lorsque vous démarrez le simulateur, l'utilisateur enregistré est renvoyé correctement!

Lorsque vous appuyez sur le bouton Ajouter en bas à droite, vous pouvez voir que les données utilisateur spécifiées dans main.dart ont été enregistrées et acquises!

Si vous avez des questions ou des suggestions, veuillez laisser un commentaire.
Recommended Posts