Git Product home page Git Product logo

flutter-generic-api-response's Introduction

Overview

This is the way I used to parse generic response object with dio package.

Concept

  • APIRoute: Manage all information about your API (url, method, headers,...)
  • APIResponse: Response objects used to wrap your API response structure.
  • APIClient: Construct to wrap http request with APIRoute, APIResponse.
  • Decodable: Interface with decodable func. Every object must be implements it to use with APIRoute.

Problem with Generic in Flutter is with T , we can not call any functions belong to this generic object. So, we can not convert it from json to object. Example:

Let's we have class User, APIClient (http request base class)

class User {
  User.fromJson(Map<String, dynamic> json) {
    // map json object with user props
  }
}

class APIClient {
   static Future<T> request<T>() {
     // make http request
     // get response
     // use response to parse from json to object T

     // problem: we can not call T.fromJson in here. Because Dart don't know what exactly is T object.
   }
}

To resolve this problem, I created a typedef function. And pass it as property to a class where we need to use generic object

typedef Create<T> = T Function();
abstract class Decodable<T> {
  T decode(dynamic data);
}

abstract class GenericObject<T> {

  // define a typedef with Decodable object
  Create<Decodable> create;

  // init object with create param
  GenericObject({ this.create });

  T genericObject(dynamic data) {
    // get create object
    final item = create();
    // now, we can call decode func from Decodable class
    return item.decode(data);
  }

}

Usage

Example: We have json:

{
  "status": true,
  "data": {
    "name": "Phong Cao"
  }
}
  1. Define a APIReponse to wrap this json structure
class APIResponse<T> extends GenericObject<T>
  implements Decodable<APIResponse<T>> {

  String status;
  T data;

  APIResponse({ Create<Decodable> create }) : super(create: create);

  @override
  APIResponse<T> decode(dynamic json) {
    status = json['status'];
    data = genericObject(json['data']);
    return this;
  }

}

GenericObject: Abstract wrapper class, it will wrap Decodable object, parse json response to object T, and return T.

I implements Decodable to override decode function. So that, we can parse APIResponse in ResponseWrapper class (ResponseWrapper is a class used to detect Success/Error response, logic in this class is same as APIResponse)

  1. Define user class
class User implements Decodable<User> {

  String name;

  @override
  User decode(dynamic json) {
    name = json['name'];
    return this;
  }
}
  1. Make a request with APIClient
Future<User> fetchUser() async {

    final client = APIClient();

    final result = await client.request(
      manager: APIRoute(APIType.getUser),
      create: () => APIResponse<User>(create: () => User())
    );

    final user = result.response.data; // reponse.data will map with User

    if (user != null) {
      return user;
    }

    throw ErrorResponse(message: 'User not found');

}

That's it! You can download my project and try Employee example to understand it clearly.

Thanks!

flutter-generic-api-response's People

Contributors

katafo avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

flutter-generic-api-response's Issues

switch-case performance

      case APIType.listEmployees:
        return RequestOptions(
            path: '/employees/all.json',
            method: APIMethod.get,
            extra: authorize);

      case APIType.detailsEmployee:
        return RequestOptions(
          path: '/employees/$routeParams.json',
          method: APIMethod.get,
        );

Hi, I am just wondering, is this use of switch-case not going to bring about performance issue when you have very high number of cases. say 100.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.