Skip to content

Build GraphQL Requests with Convertors

Convertor Replaces Strategy Registration

The Convertor pattern replaces the old strategy registration approach. There is no longer a need to register requests - Convertors compose directly.

In the Convertor pattern, GraphQL requests are built by Convertor functions that transform typed parameters into Ferry operation requests. There is no registration step - Convertors are composed directly in @riverpod providers.

@riverpod
Convertor<GQueryAttendeeReq, ListRequestParams<GattendeeFilters, GattendeeOrder>>
attendeeListQueryConvertor(Ref ref) {
return Convertor((params) {
return GQueryAttendeeReq((builder) {
builder
..requestId = 'attendee_list_${params.toString()}'
..vars.G_filter = params.filter?.toBuilder()
..vars.G_sort = params.sort?.toBuilder()
..vars.G_skip = params.skip
..vars.G_take = params.take;
});
});
}
@riverpod
Convertor<GQueryAttendeeReq, SingleRequestParams<GattendeeFilters>>
attendeeItemQueryConvertor(Ref ref) {
return Convertor((params) {
return GQueryAttendeeReq((builder) {
builder
..requestId = 'attendee_item_${params.toString()}'
..vars.G_filter = params.filter?.toBuilder()
..vars.G_take = 1;
});
});
}
@riverpod
Convertor<GMutateAttendeeSaveReq, (UpsertRequestParams<GMutateAttendeeSaveVars>, bool)>
attendeeUpsertConvertor(Ref ref) {
return Convertor((params) {
return GMutateAttendeeSaveReq((builder) {
builder
..requestId = 'attendee_upsert_${params.$1.toString()}'
..vars = params.$1.vars.toBuilder();
if (params.$2) {
builder..optimisticResponse.attendeeSave.id = '__optimistic__';
}
});
});
}
@riverpod
Convertor<GSubscribeToMessagesReq, SubscriptionRequestParams<ChatContext>>
messageSubscriptionConvertor(Ref ref) {
return Convertor((params) {
return GSubscribeToMessagesReq((builder) {
builder
..requestId = 'message_subscription'
..updateCacheHandlerContext = params.context?.toJson();
});
});
}

Request Convertors are fed into GraphQLRequestExecutor:

@riverpod
StreamConvertor<List<GQueryAttendeeData_attendee_items>,
ListRequestParams<GattendeeFilters, GattendeeOrder>>
attendeeListDatasource(Ref ref) {
return GraphQLRequestExecutor<GQueryAttendeeData,
ListRequestParams<GattendeeFilters, GattendeeOrder>, GQueryAttendeeVars>(
gqlClient: ref.watch(gqlClientProvider),
convertor: ref.watch(attendeeListQueryConvertorProvider),
)
.then(GraphQLStreamConvertor())
.map((data) => data.attendee!.items!.nonNulls.toList());
}
Before (Strategy)After (Convertor)
context.registerStrategy(ChatListRequestStrategy())ref.watch(chatListQueryConvertorProvider)
Strategy key enumNot needed
DatasourceModuleNot needed
RequestContextNot needed