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]")
GET
Dans 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!
POST
Spé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