さまざまな応答セットに対して json-annotation を使用して、さまざまな .g.dart クラスを作成しています。現在、リクエストを作成し、レスポンスをモデル クラスにマッピングするために Chopper Client を使用しているときは、コンバーターを作成しています。ただし、チョッパー クライアントに割り当てることができるコンバータは 1 つだけです。私が達成しようとしているのは、get_it パッケージを使用してチョッパー クライアントを初期化することです。異なるリクエストを行う際に、異なるコンバーターをチョッパークライアントに割り当てるにはどうすればよいですか。 これは、クラスの初期化に get_it パッケージが使用される基本クラスです。
base.dart
import 'package:chopper/chopper.dart' as chopper;
chopper.ChopperClient getBaseChopperClient(GetIt c) {
return chopper.ChopperClient(
baseUrl: 'https://',
interceptors: [chopper.HttpLoggingInterceptor()],
converter: HomeModelConverter(),
errorConverter: chopper.JsonConverter(),
);
}
c.registerLazySingleton(() {
var chopper = getBaseChopperClient(c);
return chopper;
});
c.registerFactory(() => HomeApiService.create(c<chopper.ChopperClient>()));
この ChopperService クラスから Get リクエストを作成し、HomeModelConverter を使用して応答を HomeModelResponse にマッピングします。この HomeModelConverter は、上記のチョッパー クライアント オブジェクトに割り当てられます。
home_api_service.dart
part 'home_api.chopper.dart';
@ChopperApi(baseUrl: '')
abstract class HomeApiService extends ChopperService {
@Get(path: '')
Future<Response<HomeModelResponse>> getData();
static HomeApiService create([ChopperClient? client]) =>
_$HomeApiService(client);
}
これは、HomeModelResponse 固有のコンバーター クラスです。decodeJson 関数内では、HomeModelResponse にデコードすることを明示的に言及しています。
home_model_converter.dart
class HomeModelConverter implements Converter {
@override
Request convertRequest(Request request) {
final req = applyHeader(
request,
contentTypeKey,
jsonHeaders,
override: false,
);
return encodeJson(req);
}
Request encodeJson(Request request) {
var contentType = request.headers[contentTypeKey];
if (contentType != null && contentType.contains(jsonHeaders)) {
return request.copyWith(body: json.encode(request.body));
}
return request;
}
Response<BodyType> decodeJson<BodyType, InnerType>(Response response) {
var contentType = response.headers[contentTypeKey];
var body = response.body;
if (contentType != null && contentType.contains(jsonHeaders)) {
body = utf8.decode(response.bodyBytes);
}
try {
var mapData = json.decode(body);
var popular = HomeModelResponse.fromJson(mapData);
return response.copyWith<BodyType>(body: popular as BodyType);
} catch (e) {
chopperLogger.warning(e);
return response.copyWith<BodyType>(body: body);
}
}
@override
Response<BodyType> convertResponse<BodyType, InnerType>(Response response) {
return decodeJson<BodyType, InnerType>(response);
}
}
これは、受信応答が自動的にマップされる HomeModelResponse です。
home_model_response.dart
part 'home_model_response.g.dart';
@JsonSerializable()
class HomeModelResponse {
------------
-----------
HomeModelResponse({
---------
---------
});
factory HomeModelResponse.fromJson(Map<String, dynamic> json) =>
_$HomeModelResponseFromJson(json);
Map<String, dynamic> toJson() => _$HomeModelResponseToJson(this);
}
上記のコードは home_api_service に対して正常に機能しており、適切な応答が得られています。 ここで、AddApiService などの別のサービスを作成したいと考えています。これには別のコンバーターがあります。チョッパー クライアントでコンバーターを動的に変更する方法。現在、HomeModelConverter は初期化時にハードコーディングされて割り当てられています。すべてのコンバーターに対して複数の ChopperClient を作成したくありません。ここで立ち往生。または、汎用コンバーターを作成するオプション
このアプローチが問題ないかどうか、またはフラッターに従うためのより良いアプローチがあるかどうかを誰かが提案できる場合。