GetDutchie / brick

An intuitive way to work with persistent data in Dart

Home Page:https://getdutchie.github.io/brick/#/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Getting POST When I Need PUT

SubutaDan opened this issue · comments

The REST API I am using provides a POST method for new instances and a PUT method for updates to existing instances. I thought I could get Brick to use PUT for my updates by calling upsert after setting the query action to QueryAction.update, but this doesn't seem to work. I think that may possibly be due to this piece of code in RestProvider, although I am not sure:

extension on QueryAction {
  String get httpMethod {
    switch (this) {
      case QueryAction.subscribe:
      case QueryAction.get:
        return 'GET';
      case QueryAction.insert:
      case QueryAction.update:
      case QueryAction.upsert:
        return 'POST';
      case QueryAction.delete:
        return 'DELETE';
    }
  }

How can I get Brick to send a PUT?

Thank you for your help,

Hey @SubutaDan you can specify the method within your providerArgs['request']:

final query = Query(
  providerArgs: {
    'request': RestRequest(method: 'PUT'),
  },
);
final resp = await provider.upsert<DemoRestModel>(instance, query: query);

You can also do this at the model level using a RestRequestTransformer:

class ModelRequest extends RestRequestTransformer {
  final upsert = RestRequest(url: '/my-path', method: 'PUT');

  ModelRequest(Query? query, Model? instance) : super(query, instance);
}

@ConnectOfflineFirstWithRest(
  restConfig: RestSerializable(
    requestTransformer: ModelRequest.new,
  ),
)
class Model extends OfflineFirstWithRestModel {}

@SubutaDan You can get a little crafty with the RestRequestTransformer :

class ModelRequestTransformer extends RestRequestTransformer {
  @override
  RestRequest? get upsert {
    final castModel = instance as Model?;

    // isNewRecord is a Brick method that comes from SQLite. Modify to your own purposes
    // if this doesn't represent a new record
    if (castModel?.isNewRecord ?? true) {
      return RestRequest(url: '/models/${castModel?.id}', method: 'PUT');
    }
    return const RestRequest(url: '/models');
  }

  const ModelRequestTransformer(super.query, super.instance);
}

While we're getting detailed, I noticed that the previous code I sent you was invalid, even by Dart standards. Please refer to the above code block instead.

In the code that you sent, upsert is called on "provider". This surprised me because I thought that if I want offline-first behavior I need to call my mutation methods on the Repository. Is that not correct?

Good catch. I was hastily copy/pasting from the unit tests where I get most of my answers (because I know that code runs). The one I pulled from was on the provider because it didn't need the repository. Still always use the repository instead of the individual provider.

Solved using providerArgs 'request' per your suggestion, @tshedor . Thanks again.

-Dan