如何使用free和public Rapid API并在flutter Application中调用API

How to use the free and public Rapid API and call the API in the flutter Application

例如,我订阅了一个免费的 public API 名为“https://rapidapi.com/rapidapi/api/movie-database-imdb-alternative”

其java个代码片段如下

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();

现在我的问题是如何在flutter应用中使用和调用?如果我想使用“按 ID 或标题获取”来显示电影名称,需要调用什么 url 以及 headers 的详细信息

我的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并且我已经收到密钥等

创建一个数据 class,其中包含与返回的 JSON 对象对应的字段。在不知道 JSON 字符串是什么的情况下,我无法向您展示 class 的样子。

查看 json_serializable 包以帮助您创建 class(比如 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
  }
}

这是完整的示例。您必须捏造它才能放入实际的 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? ?? '',
    );