如何使用免费和公共的 Rapid API 并在 Flutter 应用程序中调用 API
Posted
技术标签:
【中文标题】如何使用免费和公共的 Rapid API 并在 Flutter 应用程序中调用 API【英文标题】:How to use the free and public Rapid API and call the API in the flutter Application 【发布时间】:2021-11-03 21:40:11 【问题描述】:例如,我订阅了一个名为“https://rapidapi.com/rapidapi/api/movie-database-imdb-alternative”的免费公共 API
其java代码sn-ps如下
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder()
.url("https://movie-database-imdb-alternative.p.rapidapi.com/?s=Avengers%20Endgame&r=json&page=1")
.get()
.addHeader("x-rapidapi-host", "movie-database-imdb-alternative.p.rapidapi.com")
.addHeader("x-rapidapi-key", "my recieved API Key")
.build();
Response response = client.newCall(request).execute();
现在我的查询是如何在颤振应用程序中使用并调用?如果我想使用“获取 ID 或标题”来显示电影名称,则需要调用什么 url 和标题的详细信息
我的flutter代码如下
import 'dart:convert';
import 'package:http/http.dart' as http;
class APIService
// API key
// Base API url
static const String _baseUrl = "https://movie-database-imdb-alternative.p.rapidapi.com/?s=Avengers%20Endgame&r=json&page=1";
// Base headers for Response url
static const Map<String, String> _headers =
"x-rapidapi-key": "*****************",
"x-rapidapi-host": "movie-database-imdb-alternative.p.rapidapi.com",
;
// Base API request to get response
Future<dynamic> get() async
Uri uri = Uri.https(_baseUrl,"");
final response = await http.get(uri, headers: _headers);
if (response.statusCode == 200)
// If server returns an OK response, parse the JSON.
print("success");
return json.decode(response.body);
else
print("not success");
// If that response was not OK, throw an error.
throw Exception('Failed to load json data');
我想通过调用 API 在 Flutter 应用程序中显示来自 API 的图像和文本
注意:已经订阅了上面的API,我已经收到了密钥等。
【问题讨论】:
【参考方案1】:这是完整的示例。您必须捏造它才能放入实际的 JSON 查询结果:
import 'dart:convert';
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
void main()
runApp(const MyApp());
class MyApp extends StatelessWidget
const MyApp(Key? key) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context)
return MaterialApp(
debugShowCheckedModeBanner: false,
title: 'API Call Demo',
theme: ThemeData(
primarySwatch: Colors.orange,
),
initialRoute: '/',
onGenerateRoute: (settings) => onGenerateRoute(settings),
onUnknownRoute: pageNotImplementedRoute,
);
Route? onGenerateRoute(RouteSettings settings)
switch (settings.name)
case '/':
return MaterialPageRoute(
builder: (context) => const MyHomePage(),
);
case '/api_page':
return MaterialPageRoute(
builder: (context) => const MyAPIPage(),
);
default:
return null;
Route pageNotImplementedRoute(RouteSettings settings)
return MaterialPageRoute<void>(
settings: settings,
builder: (BuildContext context)
return Scaffold(
appBar: AppBar(
title: const Text('Oops!'),
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: ()
Navigator.pop(context);
,
),
),
body: Center(
child: Text(
'Page Not Implemented',
textAlign: TextAlign.center,
style: Theme.of(context).textTheme.headline6,
),
),
);
,
);
class MyHomePage extends StatefulWidget
const MyHomePage(Key? key) : super(key: key);
@override
State<MyHomePage> createState() => _MyHomePageState();
class _MyHomePageState extends State<MyHomePage>
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: const Text("Home Page"),
centerTitle: true,
),
body: Center(
child: ElevatedButton(
onPressed: () => Navigator.pushNamed(context, '/api_page'),
child: const Text("Call API"),
),
),
);
class MyAPIPage extends StatelessWidget
const MyAPIPage(Key? key) : super(key: key);
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(
title: const Text("API Page"),
centerTitle: true,
leading: IconButton(
icon: const Icon(Icons.arrow_back),
onPressed: () => Navigator.pop(context),
),
),
body: _buildBody(),
);
Widget _buildBody()
return FutureBuilder<MyData>(
future: APIService().get(),
builder: (context, snapshot)
if (snapshot.connectionState != ConnectionState.done)
return const Center(child: CircularProgressIndicator());
if (snapshot.hasError)
return Center(child: Text(snapshot.error.toString()));
if (!snapshot.hasData)
return const Center(child: Text("get() returns null!"));
final data = snapshot.data as MyData; // cast to MyData
return Container(
padding: const EdgeInsets.all(10),
color: Colors.grey,
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text("Field1"),
Text(data.field1),
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text("Field2"),
Text(data.field2),
],
),
],
),
);
,
);
class APIService
static const _authority = "sameer-kumar-aztro-v1.p.rapidapi.com";
static const _path = "/";
static const _query = "sign": "aquarius", "day": "today";
static const Map<String, String> _headers =
"x-rapidapi-key": "*****************",
"x-rapidapi-host": "sameer-kumar-aztro-v1.p.rapidapi.com",
;
// Base API request to get response
Future<MyData> get() async
Uri uri = Uri.https(_authority, _path, _query);
final response = await http.get(uri, headers: _headers);
if (response.statusCode == HttpStatus.ok)
// If server returns an OK response, parse the JSON.
final jsonMap = json.decode(response.body);
return MyData.fromJson(jsonMap);
else
// If that response was not OK, throw an error.
throw Exception('API call returned: $response.statusCode $response.reasonPhrase');
class MyData
final String field1;
final String field2;
const MyData(
this.field1 = '',
this.field2 = '',
);
factory MyData.fromJson(Map<String, dynamic> json) => _$MyDataFromJson(json);
MyData _$MyDataFromJson(Map<String, dynamic> json) => MyData(
field1: json['field1'] as String? ?? '',
field2: json['field2'] as String? ?? '',
);
【讨论】:
非常感谢您提供完整的解决方案和示例。由于 API 限制和我猜的错误密钥,任何在调用 API 之后的方式都显示为“异常:返回的 API 调用:403 禁止”。你能给我工作 API 和测试密钥吗? 我没有此 API 的密钥,但您可以试试 News API。您可以免费注册成为开发人员并获取密钥。 newsapi.org 非常感谢您的建议。我会试试的 我已经注册并收到了我通过以下方式使用的新闻 API class APIService static const _authority = "geektime.com/israeli-autotech-companies";静态常量 _path = "/"; static const _query = "sign": "aquarius", "day": "today"; static const Map创建一个数据类,其中包含与返回的 JSON 对象对应的字段。在不知道 JSON 字符串是什么的情况下,我无法向您展示该类的外观。
查看json_serializable
包以帮助您创建类(例如MyData
)并创建方法MyData.fromJson
。
然后这样做:
final jsonMap = json.decode(response.body);
return MyData.fromJson(jsonMap);
返回的MyData
对象将包含转换为 Dart 对象的 JSON 对象供您使用。
如下声明get()
:
Future<MyData> get() async
...
final jsonMap = json.decode(response.body);
return MyData.fromJson(jsonMap);
...
在您的页面小部件内build()
方法:
return FutureBuilder<MyData>(
future: get(),
builder: (context, snapshot)
if (snapshot.connectionState != ConnectionState.done)
return const Center(child: CircularProgressIndicator());
if (snapshot.hasError)
return Center(child: Text(snapshot.error));
if (!snapshot.hasData)
return Center(child: Text("get()returns null!"));
final data = snapshot.data as MyData; // cast to MyData
return Container(...); // use data in here
【讨论】:
请指导我如何从 main.dart 页面重定向到 APIPage。我的意思是我的 main.dart 代码将如何导航到 APIPage。我为 ex cricket-live-data.p.rapidapi.com/series 使用快速 API 您必须学习如何使用导航器切换到另一个页面。在 *** 上搜索示例, 我的意思是 api.dart 页面应该是怎样的,应该有 main () 函数等或没有,以及如何从 main.dart 页面返回或导航 您必须将lib
目录下的源代码树分成几个子目录。就我而言,只有main.dart
在lib
中。我还有pages
目录用于我的所有页面(屏幕)小部件,services
目录用于所有 API 调用类和方法,models
目录用于数据类(映射到 API 调用返回的 JSON 字符串),@ 987654337@ 用于自定义小部件(不是页面)。 main
指定一个主页,从主页您使用导航器push*
方法导航到其他页面。在每个页面的build
方法中调用FutureBuilder
内的API。以上是关于如何使用免费和公共的 Rapid API 并在 Flutter 应用程序中调用 API的主要内容,如果未能解决你的问题,请参考以下文章
我可以使用哪些免费和公共图像 JSON API 来测试 JSON 请求 [关闭]