Flutter generic REST API call function

Retrofit execution in Flutter

To call Rest API’s by sending dynamic headers, boundaries, print solicitation and reaction in a more custom and made sure about manner “Retrofit” is the best arrangement. To coordinate retrofit in your venture add beneath conditions in pubspec.yaml record.

1.Dependencies:

dependencies:
  retrofit: any
  logger: any
dev_dependencies:
  retrofit_generator: any
  build_runner: any

run order “ripple bar get” to download the conditions.

  1. Make a theoretical class to add base URL, retrofit setup. This is the class I have made in my application with base URL, association break and reaction break.
@RestApi(baseUrl: "https://jsonplaceholder.typicode.com")
abstract class ApiClient {
factory ApiClient(Dio dio){
dio.options = BaseOptions(receiveTimeout: 5000, connectTimeout: 5000);
return _ApiClient(dio, baseUrl: baseUrl);}
}

Retrofit creates the part document in a similar organizer as ApiClient. This document has rationale to deal with API calls.

Part file allows you to split a file into multiple dart files.

at first, the part record isn’t created so it will give a mistake at _ApiClient. To make part record run order shudder bar run build_runner fabricate it will show you cautioning “Missing “part ‘api_client.g.dart’;” Now add a section document in ApiClient for example part ‘package:api_client.g.dart’; Again run a similar order and part document will be created.

In the event that you rolled out any improvements in ApiClient, at that point likewise run a similar order to refresh part document or run order shudder bar run build_runner watch it watches changes in your venture records and naturally manufactures the records at whatever point required. It is protected to begin watcher once and leave running out of sight

  1. Programming interface announcement

Comments on technique and URL boundaries choose how the solicitation will be dealt with. Each strategy must have HTTP explanation and relative boundaries. There are implicit explanations like GET, PUT, POST, PATCH, DELETE and HEADER. Add techniques with explanations in ApiClient like underneath.

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

Technique boundaries:

@Path-To refresh the URL progressively substitution block encompassed by { } must be clarified with @Path utilizing a similar string.

@Body-Sends dart object as the solicitation body.

@Query-used to add the URL.

@Headers-to pass the headers progressively.

4.Converter: We are getting a reaction from API in JSON design which we need to change over in dart class. There are two different ways to parse JSON –

4.1 Manual Serialization: Retrofit naturally changes over the “JSON” reaction to “Post” utilizing Post.fromJson strategy.

Image for post

4.2 Automatic Serialization:

Image for post

Dependencies:

dependencies:
  json_annotation: any
dev_dependencies:
  json_serializable: any

get conditions and run vacillate bar run build_runner work to make the part record and import it in the class. Produced part document has a similar name as dart record ie “post.g.dart”

This serialization approach is better for medium to enormous activities as we don’t require transcribed standard code and grammatical mistakes. The disadvantage of this methodology is we need beginning arrangement and furthermore for each dart class part document is made which may deliver visual mess in the task.

  1. Mistake Handling :

More often than not while performing network tasks we get special cases like SocketConnectionException, ConnectionTimeout and Invalid status code. Retrofit tosses DioError which we need to deal with to evade application to be slaughtered. I have composed a ServerError class to deal with special cases.

import 'package:dio/dio.dart' hide Headers;

class ServerError implements Exception {
  int _errorCode;
  String _errorMessage = "";

  ServerError.withError({DioError error}) {
    _handleError(error);
  }

  getErrorCode() {
    return _errorCode;
  }

  getErrorMessage() {
    return _errorMessage;
  }

  _handleError(DioError error) {
    switch (error.type) {
      case DioErrorType.CANCEL:
        _errorMessage = "Request was cancelled";
        break;
      case DioErrorType.CONNECT_TIMEOUT:
        _errorMessage = "Connection timeout";
        break;
      case DioErrorType.DEFAULT:
        _errorMessage =
            "Connection failed due to internet connection";
        break;
      case DioErrorType.RECEIVE_TIMEOUT:
        _errorMessage = "Receive timeout in connection";
        break;
      case DioErrorType.RESPONSE:
        _errorMessage =
            "Received invalid status code: ${error.response.statusCode}";
        break;
      case DioErrorType.SEND_TIMEOUT:
        _errorMessage = "Receive timeout in send request";
        break;
    }
    return _errorMessage;
  }
}
  1. Reaction:

Programming interface reaction should be conventional so we can get blunder and achievement reaction by utilizing a solitary class. This is the base model to get conventional reactions.

class BaseModel<T> {
  ServerError _error;
  T data;

  setException(ServerError error) {
    _error = error;
  }

  setData(T data) {
    this.data = data;
  }

  get getException {
    return _error;
  }
}

Everything is done now how about we play out the organization activity:

import 'package:dio/dio.dart' hide Headers;

class PostUsecase {
  Dio dio;
  ApiClient apiClient;

  PostUsecase() {
    dio = new Dio();
    apiClient = new ApiClient(dio);
  }

  Future<BaseModel<Post>> getPostFromId(int id) async {
    Post response;
    try {
      response = await apiClient.getPostFromId(id);
    } catch (error, stacktrace) {
      print("Exception occured: $error stackTrace: $stacktrace");
      return BaseModel()..setException(ServerError.withError(error: error));
    }
    return BaseModel()..data = response;
  }
}

This is all about Rest API implementation in the flutter. In the next blog, we will see how to modify request & response logs.

Thank’s for reading!

Leave a Comment