Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve README with BaseResponse<T> Handling #734

Open
Abbasi233 opened this issue Jan 3, 2025 · 0 comments
Open

Improve README with BaseResponse<T> Handling #734

Abbasi233 opened this issue Jan 3, 2025 · 0 comments

Comments

@Abbasi233
Copy link

### Is your feature request related to a problem? Please describe.
First off, thanks a lot for creating such an awesome library. I’ve been using Retrofit in my Flutter project, and I handle every backend response by parsing it into a BaseResponse model. However, the body field in this model is generic, which caused me quite a bit of trouble during deserialization. I tried various approaches (Multithreading, CallAdapter etc.) and ended up spending a lot of unnecessary time on this. By chance, I discovered that adding a T body parameter alongside the Map json parameter in the BaseResponse.fromJson method allows Retrofit to handle it automatically. However, since this feature isn’t mentioned in the README, it took me a while to figure it out.

### Describe the solution you'd like
I’d love to see an example or explanation in the README showing how to work with a generic model like BaseResponse with T type body. This would make it much easier for others facing similar situations to find the right solution quickly.

### Describe alternatives you’ve considered
As an alternative, I tried manually deserializing the generic body field using custom solutions and even other deserialization libraries. However, they were either too complex or didn’t fit my project. Learning that Retrofit already supports this functionality was a game-changer and a much cleaner solution.

### Additional context
Here’s a simple example of what I’m referring to:

class BaseResponse<T> {  
  final int status;  
  final String description; 
  final T body;  

  factory BaseResponse.fromJson(Map<String, dynamic> json, T Function(Map<String, dynamic>) bodyParser) {  
    return BaseResponse(  
      status: json['status'],  
      description: json['description'],  
      body: bodyParser(json['body']),  
    );  
  }  
}  

@JsonSerializable()
class Group {
  int id;
  String name;

  Group({
    required this.id,
    required this.name,
  });

  factory Group.fromJson(Map<String, dynamic> json) => _$GroupFromJson(json);

  Map<String, dynamic> toJson() => _$GroupToJson(this);
}

RestApi class:

@RestApi(baseUrl: AppConstant.pointUrl)
abstract class GroupRestApi {
  factory GroupRestApi(Dio dio, {String baseUrl}) = _PointContractsRestApi;

  @GET('/group/findById')
  Future<HttpResponse<BaseResponse<Group>>> getGroupDetail(@Header('Authorization') String authorization, @Query('id') int id);
}

So it's generates like this:

final _result = await _dio.fetch<Map<String, dynamic>>(_options);
late BaseResponse<Group> _value;
try {
  _value = BaseResponse<Group>.fromJson(
    _result.data!,
    (json) => Group.fromJson(json as Map<String, dynamic>),
  );
} on Object catch (e, s) {
  errorLogger?.logError(e, s, _options);
  rethrow;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant