さてすぐにも UI の実装に入りたいところですが、まず外堀から埋めていきましょう。この章では前項で確認した内容を元にモデルクラスを作成していきます。
全体像
前項で Qiita API を叩いて取得するレスポンスの JSON を確認しましたが、この JSON を元にモデルクラスに変換していきます。
今回は記事自体を表す Article
モデルとユーザーを表す User
モデルを作成します。
また JSON として受け取った際に、モデルクラスに変換するためのfromJson
という factory コンストラクタも定義しておきます。
前項でも紹介したレスポンスのデータは網羅的ですが、全てを含めると大きくなってしまうので必要なデータだけピックアップし、モデルクラスを定義しましょう。
レスポンスデータ
[
{
"rendered_body": "<h1>Example</h1>",
"body": "# Example",
"coediting": false,
"comments_count": 100,
"created_at": "2000-01-01T00:00:00+00:00",
"group": {
"created_at": "2000-01-01T00:00:00+00:00",
"description": "This group is for developers.",
"name": "Dev",
"private": false,
"updated_at": "2000-01-01T00:00:00+00:00",
"url_name": "dev"
},
"id": "c686397e4a0f4f11683d",
"likes_count": 100,
"private": false,
"reactions_count": 100,
"stocks_count": 100,
"tags": [
{
"name": "Ruby",
"versions": ["0.0.1"]
}
],
"title": "Example title",
"updated_at": "2000-01-01T00:00:00+00:00",
"url": "https://qiita.com/Qiita/items/c686397e4a0f4f11683d",
"user": {
"description": "Hello, world.",
"facebook_id": "qiita",
"followees_count": 100,
"followers_count": 200,
"github_login_name": "qiitan",
"id": "qiita",
"items_count": 300,
"linkedin_id": "qiita",
"location": "Tokyo, Japan",
"name": "Qiita キータ",
"organization": "Qiita Inc.",
"permanent_id": 1,
"profile_image_url": "https://s3-ap-northeast-1.amazonaws.com/qiita-image-store/0/88/ccf90b557a406157dbb9d2d7e543dae384dbb561/large.png?1575443439",
"team_only": false,
"twitter_screen_name": "qiita",
"website_url": "https://qiita.com"
},
"page_views_count": 100,
"team_membership": {
"name": "Qiita キータ"
}
}
]
ディレクトリ配置
ファイルを作るディレクトリはお好みですが、今回はlib
直下にmodels
というディレクリを作り、モデルクラスのファイルをまとめておきましょう。
lib
├── main.dart
├── models
│ ├── article.dart
│ └── user.dart
└── screens
└── search_screen.dart
Article モデルクラスの作成
まずは記事を表すArticle
クラスを定義していきます。
こちらのデータを元に検索ページのリストを表示するので、そこで表示したい内容をピックアップしましょう。最低限必要なのはtitle
、user
辺りでしょうか。そのほかはお好みで適宜選択してみてください。今回はlikes_count
、tags
、created_at
を取得します。
...
"title": "Example title", // タイトル
"user": ..., // ユーザー
"likes_count": 100, // いいね数
"tags": ..., // タグ
"created_at": "2000-01-01T00:00:00+00:00", // 作成日時
...
また記事を表示するページでは WebView のパッケージに記事の URL を渡すので、URL も取得しておきましょう。
...
"url": "https://qiita.com/Qiita/items/c686397e4a0f4f11683d",
...
以上を含めてArticle
クラスを定義していきます。
class Article {
// コンストラクタ
Article({
required this.title,
required this.user,
required this.url,
required this.createdAt,
this.likesCount = 0,
this.tags = const [],
});
final String title;
final User user;
final String url;
final DateTime createdAt;
final int likesCount;
final List<String> tags;
}
title
,user
,url
,createdAt
は必ず存在するのでrequired
としておきます。
またuser
は後述するUser
クラスを使います。
Article
クラスへ変換
JSON→次に受け取った JSON をArticle
クラスに変換するfactory
コンストラクタを定義します。
factory Article.fromJson(Map<String, dynamic> json) {
return Article(
title: json['title'],
user: User.fromJson(json['user']),
url: json['url'],
createdAt: DateTime.parse(json['created_at'].toString()),
likesCount: json['likes_count'],
tags: List<String>.from(json['tags'].map((tag) => tag['name'])),
);
}
.fromJson
の名前は自由に変えてもらって大丈夫です。
Map<String,dynamic>
型の json を受け取り、1つ1つ展開していきます。tags
は名前だけ欲しいのでmap
で展開し、名前だけの配列に変換しています。
...
tags: List<String>.from(json['tags'].map((tag) => tag['name'])),
...
コード全体
import 'package:qiita_search/models/user.dart';
class Article {
final String title;
final User user;
final String url;
final DateTime createdAt;
final int likesCount;
final List<String> tags;
Article({
required this.title,
required this.user,
required this.url,
required this.createdAt,
this.likesCount = 0,
this.tags = const [],
});
factory Article.fromJson(Map<String, dynamic> json) {
return Article(
title: json['title'],
user: User.fromJson(json['user']),
url: json['url'],
createdAt: DateTime.parse(json['created_at'].toString()),
likesCount: json['likes_count'],
tags: List<String>.from(json['tags'].map((tag) => tag['name'])),
);
}
}
User モデルクラスの作成
User
クラスも同様に定義していきましょう。ユーザーに関するデータはレスポンスのuser
フィールド以下の部分に格納されています。
user に関するデータ
...
"user": {
"description": "Hello, world.",
"facebook_id": "qiita",
"followees_count": 100,
"followers_count": 200,
"github_login_name": "qiitan",
"id": "qiita",
"items_count": 300,
"linkedin_id": "qiita",
"location": "Tokyo, Japan",
"name": "Qiita キータ",
"organization": "Qiita Inc.",
"permanent_id": 1,
"profile_image_url": "https://s3-ap-northeast-1.amazonaws.com/qiita-image-store/0/88/ccf90b557a406157dbb9d2d7e543dae384dbb561/large.png?1575443439",
"team_only": false,
"twitter_screen_name": "qiita",
"website_url": "https://qiita.com"
},
...
こちらもお好みですが今回はid
とprofinle_image_url
を取得しておきましょう。
...
"id": "qiita",
"profile_image_url": "https://s3-ap-northeast-1.amazonaws.com/qiita-image-store/0/88/ccf90b557a406157dbb9d2d7e543dae384dbb561/large.png?1575443439",
...
以上を含めてUser
クラスを定義していきます。
class User {
final String id;
final String profileImageUrl;
User({
required this.id,
required this.profileImageUrl,
});
}
次にArticle
クラス同様に fromJson と名付けた、factory コンストラクタを定義しましょう。
factory User.fromJson(Map<String, dynamic> json) {
return User(
id: json['id'],
profileImageUrl: json['profile_image_url'],
);
}
コード全体
class User {
final String id;
final String profileImageUrl;
User({
required this.id,
required this.profileImageUrl,
});
factory User.fromJson(Map<String, dynamic> json) {
return User(
id: json['id'],
profileImageUrl: json['profile_image_url'],
);
}
}
まとめ
以上で API から取得したデータを格納するモデルクラスが出来ました。
次章では、API 通信を行い、データを取得し、今回定義したモデルクラスに格納する処理を実装していきます。