最近、 Deno + Oakで(データベースを使用せずに)TodoAPIを作成する方法について書きました 。リポジトリはchapter_1:oakにあります。 GitHubで。
このチュートリアルでは、もう一方が中断したところを取り上げ、MySQLをDenoおよびOakプロジェクトに統合する方法について説明します。
このチュートリアルで使用されているソースコード全体をいつでも確認したい場合は、 chapter_2:mysqlで入手できます。 。よろしければ、GitHubでスターを付けてください。
上記の最後のチュートリアルをすでに完了していることを前提としています。そうでない場合は、ここで確認して、終了したら戻ってきてください。
開始する前に、MySQLクライアントがインストールされて実行されていることを確認してください。
- MySQLコミュニティサーバー[ここからダウンロード]
- MySQLWorkbench[ここからダウンロード]
私も苦労したので、MySQLのセットアップに関するMacOSユーザー向けの小さなガイドを書きました。こちらでチェックしてください。
Windowsマシンを使用している場合は、同じツールを使用するか、XAMPPを使用してダッシュボードでMySQLインスタンスを実行することもできます。
MySQLインスタンスを実行したら、チュートリアルを開始できます。
この記事から来ていると仮定すると、 Deno +OakのTodoAPI(データベースを使用しない) 、次のことを行います:
- MySQLデータベース接続を作成する
- Denoサーバーを起動するたびにデータベースをリセットする小さなスクリプトを作成します
- テーブルでCRUD操作を実行する
- APIコントローラーにCRUD機能を追加する
最後にもう1つ、MySQLをプロジェクトに追加するために第1章で行われたコミットの違い全体を示します(第1章から行われた新しい追加を示すソースコード)。
プロジェクトのルートフォルダ内–私の名前は chapter_2:mysql
です。 、 あなたは好きなように呼び出すことができます– dbというフォルダを作成します 。そのフォルダ内に、config.tsおよびというファイルを作成します 次のコンテンツを追加します:
export const DATABASE: string = "deno";
export const TABLE = {
TODO: "todo",
};
ここでは特別なことは何もありません。データベース名をテーブルのオブジェクトと一緒に定義してからエクスポートするだけです。このプロジェクトには「deno」というデータベースが1つあり、そのデータベース内には「todo」というテーブルが1つだけあります。
次に、 db内 フォルダに、 client.tsという別のファイルを作成します 次のコンテンツを追加します:
import { Client } from "https://deno.land/x/mysql/mod.ts";
// config
import { DATABASE, TABLE } from "./config.ts";
const client = await new Client();
client.connect({
hostname: "127.0.0.1",
username: "root",
password: "",
db: "",
});
export default client;
ここでいくつかのことが起こっています。
Client
をインポートしています mysql
から 図書館。 クライアント
データベースに接続し、データベースで操作を実行するのに役立ちます。
client.connect({
hostname: "127.0.0.1",
username: "root",
password: "",
db: "",
});
クライアント
connect
と呼ばれるメソッドを提供します これは、 hostname
を提供できるオブジェクトを取り込みます 、 username
、 password
、および db
。この情報を使用して、MySQLインスタンスへの接続を確立できます。
ユーザー名
を確認してください パスワード
がありません 、DenoのMySQLライブラリへの接続と競合するため。その方法がわからない場合は、私が書いたこのチュートリアルを読んでください。
データベース
を離れました スクリプトの後半で手動で選択するため、ここではフィールドを空白にします。
「deno」というデータベースを初期化するスクリプトを追加して選択し、そのデータベース内に「todo」というテーブルを作成しましょう。
db / client.ts
の内部 ファイルいくつかの新しい追加を行いましょう:
import { Client } from "https://deno.land/x/mysql/mod.ts";
// config
import { DATABASE, TABLE } from "./config.ts";
const client = await new Client();
client.connect({
hostname: "127.0.0.1",
username: "root",
password: "",
db: "",
});
const run = async () => {
// create database (if not created before)
await client.execute(`CREATE DATABASE IF NOT EXISTS ${DATABASE}`);
// select db
await client.execute(`USE ${DATABASE}`);
// delete table if it exists before
await client.execute(`DROP TABLE IF EXISTS ${TABLE.TODO}`);
// create table
await client.execute(`
CREATE TABLE ${TABLE.TODO} (
id int(11) NOT NULL AUTO_INCREMENT,
todo varchar(100) NOT NULL,
isCompleted boolean NOT NULL default false,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`);
};
run();
export default client;
ここでは、 DATABASE
をインポートしています およびTABLE
構成ファイルから、 run()
という新しい関数でこれらの値を使用します 。
このrun()
を分解してみましょう 働き。ワークフローを理解するのに役立つコメントをファイルに追加しました:
const run = async () => {
// create database (if not created before)
await client.execute(`CREATE DATABASE IF NOT EXISTS ${DATABASE}`);
// select db
await client.execute(`USE ${DATABASE}`);
// delete table if it exists before
await client.execute(`DROP TABLE IF EXISTS ${TABLE.TODO}`);
// create table
await client.execute(`
CREATE TABLE ${TABLE.TODO} (
id int(11) NOT NULL AUTO_INCREMENT,
todo varchar(100) NOT NULL,
isCompleted boolean NOT NULL default false,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
`);
};
run();
-
deno
というデータベースを作成します 。すでに存在する場合は、何もしません。 - 次に、使用するデータベースを選択します。これは
deno
と呼ばれます。 -
deno
内のテーブルを削除しますtodo
と呼ばれます すでに存在する場合。 - 次に、
deno
内に新しいテーブルを作成します db、それをtodo
と呼びます 、およびその構造を定義します。一意の自動増分id
があります。 これは整数になり、todo
と呼ばれる別のフィールドになります これは文字列になり、最後にisCompleted
というフィールドになります これはブール値です。id
も定義します 主キーとして。
このスクリプトを作成した理由は、MySQLインスタンスに追加情報を入れたくないためです。スクリプトを実行するたびに、すべてが再初期化されます。
このスクリプトを追加する必要はありません。ただし、そうでない場合は、データベースとテーブルを手動で作成する必要があります。
また、データベースの作成とテーブルの作成に関するDenoMySQLライブラリのドキュメントも確認してください。
議事に戻ると、記事の冒頭で述べた4つのうち2つを達成しました。
- MySQLデータベース接続を作成する
- Denoサーバーを起動するたびにデータベースをリセットする小さなスクリプトを作成します
それはすでにチュートリアルの50%です。残念ながら、現在、多くのことが起こっているのを見ることができません。いくつかの機能をすばやく追加して、機能することを確認しましょう。
テーブルでCRUD操作を実行し、APIコントローラーに機能を追加する
最初にTodoインターフェースを更新する必要があります。 interfaces / Todo.ts
に移動します ファイルを作成し、以下を追加します:
export default interface Todo {
id?: number,
todo?: string,
isCompleted?: boolean,
}
このは何ですか?コード> オブジェクトのキーをオプションにします。これを行ったのは、後でさまざまな関数を使用して、
id
のみを持つオブジェクトを渡すためです。 、 todo
、 isCompleted
、またはそれらすべてを一度に。
TypeScriptのオプションのプロパティについて詳しく知りたい場合は、こちらのドキュメントにアクセスしてください。
次に、モデルという名前の新しいフォルダを作成します そのフォルダ内に、 todo.tsというファイルを作成します 。 次のコンテンツをファイルに追加します:
import client from "../db/client.ts";
// config
import { TABLE } from "../db/config.ts";
// Interface
import Todo from "../interfaces/Todo.ts";
export default {
/**
* Takes in the id params & checks if the todo item exists
* in the database
* @param id
* @returns boolean to tell if an entry of todo exits in table
*/
doesExistById: async ({ id }: Todo) => {},
/**
* Will return all the entries in the todo column
* @returns array of todos
*/
getAll: async () => {},
/**
* Takes in the id params & returns the todo item found
* against it.
* @param id
* @returns object of todo item
*/
getById: async ({ id }: Todo) => {},
/**
* Adds a new todo item to todo table
* @param todo
* @param isCompleted
*/
add: async (
{ todo, isCompleted }: Todo,
) => {},
/**
* Updates the content of a single todo item
* @param id
* @param todo
* @param isCompleted
* @returns integer (count of effect rows)
*/
updateById: async ({ id, todo, isCompleted }: Todo) => {},
/**
* Deletes a todo by ID
* @param id
* @returns integer (count of effect rows)
*/
deleteById: async ({ id }: Todo) => {},
};
現在、関数は空ですが、それは問題ありません。 1つずつ埋めていきます。
次に、 controllers / todo.ts
に移動します ファイルを作成し、次を追加してください:
// interfaces
import Todo from "../interfaces/Todo.ts";
// models
import TodoModel from "../models/todo.ts";
export default {
/**
* @description Get all todos
* @route GET /todos
*/
getAllTodos: async ({ response }: { response: any }) => {},
/**
* @description Add a new todo
* @route POST /todos
*/
createTodo: async (
{ request, response }: { request: any; response: any },
) => {},
/**
* @description Get todo by id
* @route GET todos/:id
*/
getTodoById: async (
{ params, response }: { params: { id: string }; response: any },
) => {},
/**
* @description Update todo by id
* @route PUT todos/:id
*/
updateTodoById: async (
{ params, request, response }: {
params: { id: string };
request: any;
response: any;
},
) => {},
/**
* @description Delete todo by id
* @route DELETE todos/:id
*/
deleteTodoById: async (
{ params, response }: { params: { id: string }; response: any },
) => {},
};
ここにも空の関数があります。それらを埋め始めましょう。
[Get]すべてのtodosAPI
models / todo.ts
の内部 、 getAll
という関数の定義を追加します :
import client from "../db/client.ts";
// config
import { TABLE } from "../db/config.ts";
// Interface
import Todo from "../interfaces/Todo.ts";
export default {
/**
* Will return all the entries in the todo column
* @returns array of todos
*/
getAll: async () => {
return await client.query(`SELECT * FROM ${TABLE.TODO}`);
},
}
クライアント
connect
以外の別のメソッドも公開します ( db / client.ts
で「接続」メソッドを使用しました ファイル)そしてそれは query
。 client.query
メソッドを使用すると、Denoコードから直接MySQLクエリをそのまま実行できます。
次に、 controllers / todo.ts
に移動します getAllTodos
の定義を追加します :
// interfaces
import Todo from "../interfaces/Todo.ts";
// models
import TodoModel from "../models/todo.ts";
export default {
/**
* @description Get all todos
* @route GET /todos
*/
getAllTodos: async ({ response }: { response: any }) => {
try {
const data = await TodoModel.getAll();
response.status = 200;
response.body = {
success: true,
data,
};
} catch (error) {
response.status = 400;
response.body = {
success: false,
message: `Error: ${error}`,
};
}
},
}
TodoModel
をインポートするだけです getAll
というメソッドを使用します 、今定義したばかりです。約束として返されるので、async/awaitでラップしました。
メソッドTodoModel.getAll()
response.body
に返すだけの配列を返します status
200
に設定 。
promiseが失敗した場合、または別のエラーが発生した場合は、catchブロックに移動し、 success
でステータス400を返します。 falseに設定します。 メッセージ
も設定します キャッチブロックから得られるものに。
以上で完了です。それでは、ターミナルを起動しましょう。
MySQLインスタンスが実行されていることを確認してください。端末のタイプ:
$ deno run --allow-net server.ts
端末は次のようになります。
私のコンソールはここで2つのことを教えてくれます。
- DenoAPIサーバーがポート8080で実行されていること
- MySQLインスタンスが
127.0.0.1
で実行されていること 、これはlocalhost
です
APIをテストしてみましょう。ここではPostmanを使用していますが、お気に入りのAPIクライアントを使用できます。
現在、空のデータのみを返します。ただし、 todo
にデータを追加すると テーブルの場合、これらのToDoがここに返されます。
素晴らしい。 1つのAPIがダウンし、さらに4つ残ります。
[投稿]todoAPIを追加
models / todo.ts
内 ファイルに、 add()
の次の定義を追加します 機能:
export default {
/**
* Adds a new todo item to todo table
* @param todo
* @param isCompleted
*/
add: async (
{ todo, isCompleted }: Todo,
) => {
return await client.query(
`INSERT INTO ${TABLE.TODO}(todo, isCompleted) values(?, ?)`,
[
todo,
isCompleted,
],
);
},
}
add関数は、オブジェクトを引数として受け取ります。これには、 todo
という2つの項目があります。 およびisCompleted
。
したがって、追加 :非同期 ({todo、isCompleted}:Todo)=> {}
({todo、isCompleted}:{todo:string、isCompleted:boolean})
と書くこともできます 。ただし、 interfaces / Todo.ts
で既にインターフェイスが定義されているため
export default interface Todo {
id?: number,
todo?: string,
isCompleted?: boolean,
}
これは、 addと簡単に書くことができます。 :非同期 ({todo、isCompleted}:Todo)=> {}
。これは、この関数に todo
という2つの引数があることをTypeScriptに通知します。 、これは文字列であり、 isCompleted
、これはブール値です。
インターフェイスについて詳しく知りたい場合は、TypeScriptに優れたドキュメントがあります。ここで見つけることができます。
関数内には次のものがあります:
return await client.query(
`INSERT INTO ${TABLE.TODO}(todo, isCompleted) values(?, ?)`,
[
todo,
isCompleted,
],
);
このクエリは2つの部分に分けることができます:
-
INSERT INTO ${TABLE。 TODO}(todo、isCompleted)values(?、?)
。ここでの2つの疑問符は、このクエリ内での変数の使用を示しています。 - 他の部分、
[todo、isCompleted]
、は最初の部分に入る変数です クエリの(?、?)
に置き換えられます -
Table.Todo
ファイルdb/ config.ts
からの単なる文字列です ここで、Table.Todo
値は「todo
」です "
次はcontrollers/ todo.ts
の内部です ファイルの場合は、 createTodo()
の定義に移動します 機能:
export default {
/**
* @description Add a new todo
* @route POST /todos
*/
createTodo: async (
{ request, response }: { request: any; response: any },
) => {
const body = await request.body();
if (!request.hasBody) {
response.status = 400;
response.body = {
success: false,
message: "No data provided",
};
return;
}
try {
await TodoModel.add(
{ todo: body.value.todo, isCompleted: false },
);
response.body = {
success: true,
message: "The record was added successfully",
};
} catch (error) {
response.status = 400;
response.body = {
success: false,
message: `Error: ${error}`,
};
}
},
}
これを2つの部分に分けてみましょう:
パート1
const body = await request.body();
if (!request.hasBody) {
response.status = 400;
response.body = {
success: false,
message: "No data provided",
};
return;
}
ここで行っているのは、ユーザーが本文でデータを送信しているかどうかを確認することだけです。そうでない場合は、ステータス 400
を返します。 そして本文でsuccess:false
を返します およびmessage:
。
パート2
try {
await TodoModel.add(
{ todo: body.value.todo, isCompleted: false },
);
response.body = {
success: true,
message: "The record was added successfully",
};
} catch (error) {
response.status = 400;
response.body = {
success: false,
message: `Error: ${error}`,
};
}
エラーがない場合は、 TodoModel.add()
関数が呼び出され、 200
のステータスを返すだけです。 とユーザーへの確認メッセージ。
それ以外の場合は、以前のAPIで行ったのと同様のエラーがスローされます。
これで完了です。ターミナルを起動し、MySQLインスタンスが実行されていることを確認します。端末のタイプ:
$ deno run --allow-net server.ts
Postmanに移動し、このコントローラーのAPIルートを実行します:
これは素晴らしいことです。現在、2つのAPIが機能しています。あと3つだけです。
[GET] todo by id API
models / todo.ts
で ファイルに、これら2つの関数の定義を追加します。 doesExistById()
およびgetById()
:
export default {
/**
* Takes in the id params & checks if the todo item exists
* in the database
* @param id
* @returns boolean to tell if an entry of todo exits in table
*/
doesExistById: async ({ id }: Todo) => {
const [result] = await client.query(
`SELECT COUNT(*) count FROM ${TABLE.TODO} WHERE id = ? LIMIT 1`,
[id],
);
return result.count > 0;
},
/**
* Takes in the id params & returns the todo item found
* against it.
* @param id
* @returns object of todo item
*/
getById: async ({ id }: Todo) => {
return await client.query(
`SELECT * FROM ${TABLE.TODO} WHERE id = ?`,
[id],
);
},
}
各機能について1つずつ話しましょう:
-
doesExistById
id
を受け取りますboolean
を返します 特定のToDoがデータベースに存在するかどうかを示します。
この関数を分解してみましょう:
const [result] = await client.query(
`SELECT COUNT(*) count FROM ${TABLE.TODO} WHERE id = ? LIMIT 1`,
[id],
);
return result.count > 0;
この表のカウントを特定のtodoIDと照合するだけです。カウントがゼロより大きい場合、 true
を返します。 。それ以外の場合は、 false
を返します。 。
-
getById
特定のIDに対してtodoアイテムを返します:
return await client.query(
`SELECT * FROM ${TABLE.TODO} WHERE id = ?`,
[id],
);
ここでは、MySQLクエリを実行して、IDでToDoを取得し、結果をそのまま返します。
次に、 controllers / todo.ts
に移動します ファイルを作成し、 getTodoById
の定義を追加します コントローラ方式:
export default {
/**
* @description Get todo by id
* @route GET todos/:id
*/
getTodoById: async (
{ params, response }: { params: { id: string }; response: any },
) => {
try {
const isAvailable = await TodoModel.doesExistById(
{ id: Number(params.id) },
);
if (!isAvailable) {
response.status = 404;
response.body = {
success: false,
message: "No todo found",
};
return;
}
const todo = await TodoModel.getById({ id: Number(params.id) });
response.status = 200;
response.body = {
success: true,
data: todo,
};
} catch (error) {
response.status = 400;
response.body = {
success: false,
message: `Error: ${error}`,
};
}
},
}
これを2つの小さな部分に分けてみましょう:
const isAvailable = await TodoModel.doesExistById(
{ id: Number(params.id) },
);
if (!isAvailable) {
response.status = 404;
response.body = {
success: false,
message: "No todo found",
};
return;
}
まず、次の方法を使用して、todoがIDに対してデータベースに存在するかどうかを確認します。
const isAvailable = await TodoModel.doesExistById(
{ id: Number(params.id) },
);
ここでは、 params.id
を変換する必要があります Number
に ToDoインターフェースはid
のみを受け入れるためです 数として。次に、 params.id
を渡します。 doesExistById
に 方法。このメソッドはブール値として返されます。
次に、todoが利用できないかどうかを確認し、 404
を返します。 以前のエンドポイントと同様に、標準の応答を使用する方法:
if (!isAvailable) {
response.status = 404;
response.body = {
success: false,
message: "No todo found",
};
return;
}
次に、次のようになります。
try {
const todo: Todo = await TodoModel.getById({ id: Number(params.id) });
response.status = 200;
response.body = {
success: true,
data: todo,
};
} catch (error) {
response.status = 400;
response.body = {
success: false,
message: `Error: ${error}`,
};
これは、以前のAPIで行っていたものと似ています。ここでは、変数 todo
を設定して、dbからデータを取得しているだけです。 、そして応答を返します。エラーが発生した場合は、catchブロックの標準エラーメッセージをユーザーに返すだけです。
次に、ターミナルを起動し、MySQLインスタンスが実行されていることを確認します。端末のタイプ:
$ deno run --allow-net server.ts
Postmanに移動し、このコントローラーのAPIルートを実行します。
サーバーを再起動するたびに、データベースをリセットすることを忘れないでください。この動作を望まない場合は、 run
をコメントアウトするだけです。 ファイルdb/ client.ts
の関数 。
これまでのところ、以下のAPIを実行しています:
- すべてのタスクを取得する
- 新しいToDoを作成する
- IDでToDoを取得する
残りのAPIは次のとおりです:
- IDでToDoを更新する
- IDでToDoを削除する
[PUT]idAPIによるtodoの更新
まず、このAPIのモデルを作成しましょう。 models / todo.ts
にアクセスしてください ファイルを作成し、 updateById
の定義を追加します 機能:
**
* Updates the content of a single todo item
* @param id
* @param todo
* @param isCompleted
* @returns integer (count of effect rows)
*/
updateById: async ({ id, todo, isCompleted }: Todo) => {
const result = await client.query(
`UPDATE ${TABLE.TODO} SET todo=?, isCompleted=? WHERE id=?`,
[
todo,
isCompleted,
id,
],
);
// return count of rows updated
return result.affectedRows;
},
updateById
3つのパラメータを取ります: id
、 todo
、および isCompleted
。
この関数内でMySQLクエリを実行するだけです:
onst result = await client.query(
`UPDATE ${TABLE.TODO} SET todo=?, isCompleted=? WHERE id=?`,
[
todo,
isCompleted,
id,
],
);
これにより、単一のToDoアイテムの todo
が更新されます およびisCompleted
特定のid
による 。
次に、次のようにして、このクエリによって更新された行数を返します。
// return count of rows updated
return result.affectedRows;
カウントは0または1になりますが、1を超えることはありません。これは、データベースに一意のIDがあるためです。同じIDを持つ複数のtodoは存在できません。
次に、 controllers / todo.ts
に移動します ファイルを作成し、 updateTodoById
の定義を追加します 機能:
updateTodoById: async (
{ params, request, response }: {
params: { id: string };
request: any;
response: any;
},
) => {
try {
const isAvailable = await TodoModel.doesExistById(
{ id: Number(params.id) },
);
if (!isAvailable) {
response.status = 404;
response.body = {
success: false,
message: "No todo found",
};
return;
}
// if todo found then update todo
const body = await request.body();
const updatedRows = await TodoModel.updateById({
id: Number(params.id),
...body.value,
});
response.status = 200;
response.body = {
success: true,
message: `Successfully updated ${updatedRows} row(s)`,
};
} catch (error) {
response.status = 400;
response.body = {
success: false,
message: `Error: ${error}`,
};
}
},
これは、以前に作成したAPIとほぼ同じです。ここで新しい部分はこれです:
// if todo found then update todo
const body = await request.body();
const updatedRows = await TodoModel.updateById({
id: Number(params.id),
...body.value,
});
ユーザーがJSONで送信した本文を取得し、その本文を TodoModel.updateById
に渡すだけです。 機能。
id
を変換する必要があります Todoインターフェースに準拠するための番号に。
クエリが実行され、更新された行の数が返されます。そこから、応答でそれを返すだけです。エラーが発生した場合は、catchブロックに移動し、標準の応答メッセージを返します。
これを実行して、機能するかどうかを確認してみましょう。 MySQLインスタンスが実行されていることを確認し、ターミナルから次を実行します。
$ deno run --allow-net server.ts
Postmanに移動し、このコントローラーのAPIルートを実行します:
[DELETE] todo by id API
models / todo.ts
で ファイルはdeleteById
という関数を作成します :
/**
* Deletes a todo by ID
* @param id
* @returns integer (count of effect rows)
*/
deleteById: async ({ id }: Todo) => {
const result = await client.query(
`DELETE FROM ${TABLE.TODO} WHERE id = ?`,
[id],
);
// return count of rows updated
return result.affectedRows;
},
ここでは、 id
を渡すだけです。 パラメータとして、MySQLの削除クエリを使用します。次に、更新された行数を返します。各todoのIDは一意であるため、更新されるカウントは0または1になります。
次に、 controllers / todo.ts
に移動します ファイルを作成し、 deleteByTodoId
を定義します 方法:
/**
* @description Delete todo by id
* @route DELETE todos/:id
*/
deleteTodoById: async (
{ params, response }: { params: { id: string }; response: any },
) => {
try {
const updatedRows = await TodoModel.deleteById({
id: Number(params.id),
});
response.status = 200;
response.body = {
success: true,
message: `Successfully updated ${updatedRows} row(s)`,
};
} catch (error) {
response.status = 400;
response.body = {
success: false,
message: `Error: ${error}`,
};
}
},
これは非常に簡単です。 params.id
を渡します TodoModel.deleteById
に メソッドを実行し、このクエリで更新された行数を返します。
何か問題が発生した場合、catchブロックにエラーがスローされ、標準のエラー応答が返されます。
これをチェックしてみましょう。
MySQLインスタンスが実行されていることを確認してください。端末のタイプ:
$ deno run --allow-net server.ts
Postmanに移動し、このコントローラーのAPIルートを実行します:
これで、Deno + Oak+MySQLチュートリアルが完了しました。
ソースコード全体は、https://github.com/adeelibr/deno-playgroundから入手できます。問題を見つけたら、私に知らせてください。または、お気軽にプルリクエストを行ってください。リポジトリにクレジットを差し上げます。
このチュートリアルが役に立った場合は、共有してください。そしていつものように、私はツイッターの@adeelibrで利用できます。それについてのあなたの考えを聞いてみたいです。