Retrofit — A maneira mais fácil de chamar APIs Rest no Flutter
Flutter contém módulos de Networking e JSON serialization. Para os pequenos dados JSON, ainda precisamos escrever muito mais código clichê, pois o Dart não oferece suporte à reflexão (o Gson o usa).
Se você trabalhou em Android ou iOS, talvez já tenha usado bibliotecas como Retrofit e Alamofire. Como usamos chamadas de API Rest em quase todos os aplicativos, elas agora são uma parte crucial do funcionamento do aplicativo. Essas bibliotecas cuidam de toda a análise de dados e isso torna a API chamada moleza.
Neste post, vamos aprender como usar a biblioteca Retrofit no Flutter.
Para chamar APIs Rest enviando cabeçalhos dinâmicos, parâmetros, solicitação e resposta de maneira personalizada e segura, “Retrofit” é a melhor maneira.
Vamos sujar as mãos!! 🙌🏻 😄
Etapa 1: criar um aplicativo Flutter
Etapa 2: Para trabalhar com a implementação do Retrofit no flutter, precisamos adicionar as dependências abaixo no arquivo pubspec.yaml.
dependencies: retrofit: ^4.0.1 dio: ^4.0.6 built_value: ^8.4.4 json_annotation: ^4.8.0 dev_dependencies: retrofit_generator: ^6.0.0+2 build_runner: ^2.3.3 json_serializable: ^6.6.1 built_value_generator: ^8.4.4
Dio é nosso cliente Http e cuida da conexão para nós.
Retrofit é um cliente Dio que facilita o consumo de APIs Rest.
Build runner é usado para geração de código no Dart, além do pub.
JSON Serialization cria uma classe de modelo a partir de dados JSON.
Etapa 3: Para demonstrar a chamada de API neste exemplo, usaremos esta API pública: https://gorest.co.in/public-api/users
Vamos criar uma classe abstrata ApiRequest & APIs
///APIs class is for api tags class Apis { static const String users = '/users'; } @RestApi(baseUrl: "https://gorest.co.in/public-api/") abstract class ApiClient { factory ApiClient(Dio dio, {String baseUrl}) = _ApiClient; @GET(Apis.users) Future<ResponseData> getUsers(); }
A classe ApiClient é responsável por lidar com todos os métodos de chamada de rede. No código acima, apresentará um erro na variável _ApiClient, que será resolvido com os passos que veremos mais adiante neste post.
As anotações no método e no parâmetro de URL decidem como a solicitação será tratada. Todo método deve ter anotação HTTP e parâmetros relativos. Existem algumas anotações internas como GET, PUT, POST, PATCH, DELETE & HEADER. Adicione métodos com anotações no ApiClient como acima.
Aqui está um exemplo com diferentes anotações. (Pode não corresponder ao baseURL.)
//Dynamic headers @GET("/posts") Future<List<Post>> getPosts(@Header("Content-Type") String contentType ); @GET("/comments") @Headers(<String, dynamic>{ //Static header "Content-Type" : "application/json", "Custom-Header" : "Your header" }) Future<List<Comment>> getAllComments(); @GET("/posts/{id}") Future<Post> getPostFromId(@Path("id") int postId); @GET("/comments?postId={id}") Future<Comment> getCommentFromPostId(@Path("id") int postId); @GET("/comments") Future<Comment> getCommentFromPostIdWithQuery(@Query("postId") int postId); //This yields to "/comments?postId=postId @DELETE("/posts/{id}") Future<void> deletePost(@Path("id") int postId); @POST("/posts") Future<Post> createPost(@Body() Post post);
Parâmetros do método:
@Path– Para atualizar a URL dinamicamente, o bloco de substituição entre { } deve ser anotado com @Path usando a mesma string.
@Body– Envia o objeto de dardo como o corpo da solicitação.
@Query– usado para anexar o URL.
@Headers– para passar os cabeçalhos dinamicamente.
Para resolver o erro precisamos adicionar a parte ‘api_client.g.dart’; na declaração de importação. Ele mostrará o aviso “Missing “part ‘api_client.g.dart’;
Execute o comando: flutter pub run build_runner build
O arquivo de peça permite dividir um arquivo em vários arquivos dart.
O comando acima irá gerar o arquivo api_client.g.dart e contém todos os dados sobre a criação da instância do Retrofit e a busca de dados da rede.
Se você fez alguma alteração no ApiClient, execute também o comando para atualizar o arquivo de peça ou execute commend flutter pub run build_runner watch as alterações nos arquivos do projeto e crie automaticamente os arquivos sempre que necessário. É seguro iniciar o observador uma vez e deixá-lo rodando em segundo plano.
Etapa 4: criar classes de dados
Nossa API retornará uma lista de usuários. Adicionando uma amostra de dados de API { code: 200, meta: { pagination: { total: 1676, pages: 84, page: 1, limit: 20 } }, data: [ { id: 1, name: "Mrs. Somnath Namboothiri", email: "somnath_namboothiri_mrs@baumbach-nitzsche.com", gender: "Female", status: "Active", created_at: "2020–08–31T03:50:04.198+05:30", updated_at: "2020–08–31T03:50:04.198+05:30" }, ] }
Vamos criar um data.dart e adicionar o código abaixo.
Existem duas maneiras de analisar o JSON.
I) Serialização Manual: Estamos recebendo uma resposta da API no formato JSON que temos que converter em classe dart.
class User { int id; String name; String email; String gender; String status; String created_at; String updated_at; User({this.id, this.name, this.email,this.gender, this.status, this.created_at, this.updated_at}); factory User.fromJson(Map<String, dynamic> json) { return User( id: json['id'], name: json['name'], email: json['email'], gender: json['gender'], status: json['status'], created_at: json['created_at'], updated_at: json['updated_at'], ); } Map<String, dynamic> toJson() { return { 'id': id, 'name': name, 'email': email, 'gender': gender, 'status': status, 'created_at': created_at, 'updated_at': updated_at, }; } }
II) Serialização Automática: O Retrofit converte automaticamente a resposta “JSON” para a classe “User” no dart usando a classe User do JSON.
O código abaixo fará a serialização automática dos dados JSON.
Nesse momento, ele mostrará erros. Então vamos rodar o comando abaixo novamente e gerar a parte ‘data.g.dart’;
Execute o comando: flutter pub run build_runner build
import 'package:json_annotation/json_annotation.dart'; part 'data.g.dart'; @JsonSerializable() class User{ int id; String name; String email; String gender; String status; String created_at; String updated_at; User({this.id, this.name, this.email,this.gender, this.status, this.created_at, this.updated_at}); factory User.fromJson(Map<String, dynamic> json) => _$UserFromJson(json); Map<String, dynamic> toJson() => _$UserToJson(this); } @JsonSerializable() class ResponseData{ int code; dynamic meta; List<dynamic>data; ResponseData({this.code, this.meta, this.data}); factory ResponseData.fromJson(Map<String, dynamic> json) => _$ResponseDataFromJson(json); Map<String, dynamic> toJson() => _$ResponseDataToJson(this); }
Essa abordagem de serialização é melhor para projetos de médio a grande porte, pois não precisamos de código clichê manuscrito. A desvantagem dessa abordagem é que precisamos de uma configuração inicial e, também, para cada classe de dardo, é criado um arquivo de peça que pode produzir desordem visual no projeto.
Etapa 5: vamos chamar a API com o objeto retrofit
FutureBuilder<ResponseData> _buildBody(BuildContext context) { final client = ApiClient(Dio(BaseOptions(contentType: "application/json"))); return FutureBuilder<ResponseData>( future: client.getUsers(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.done) { final ResponseData posts = snapshot.data; return _buildListView(context, posts); } else { return Center( child: CircularProgressIndicator(), ); } }, ); }
Codificação feliz !! 🙂
Criei uma demonstração usando as dependências e etapas acima em um flutter.
Você pode encontrar o código-fonte deste post no seguinte repositório do Github:
https://github.com/caneto/flutter_retrofit
Há muito o que explorar com o Flutter, o seguinte link para o site oficial tem muito material útil relacionado a chamadas de API, que vale a pena dar uma olhada.
https://flutter.dev/docs/development/data-and-backend/json
Gostei muito de construir Listview usando chamada de API de retrofit com Flutter, pois permite chamar APIs enquanto escreve muito poucas linhas de código. Continuarei explorando diferentes estruturas e bibliotecas do Flutter,
Por favor, dê alguns 👏 se você gosta do que lê e siga-nos para se manter atualizado com nossas últimas postagens.