mutualmobile/MMRecord

Correct way to send data to MMServer subclass

Closed this issue · 5 comments

I'm having some trouble trying to find a neat way to pass some data that my Server sub class needs to use. How do you distinguish if a request needs to be performed with an GET HTTP Verb or POST? Do you send this "metadata" in the data param in

[startRequestWithURN: data: context: domain: resultBlock: failureBlock:];

Any suggestion are more than welcome!

Generally speaking, you'll only implement your server class to use GET or POST. In most cases it should be GET, except in scenarios where your API uses POST methods to obtain data (not common, but does happen sometimes). MMRecord isn't really designed to be used for updating data, so it doesn't really work the same way as AFNetworking which fully supports all types of HTTP methods. Theres nothing preventing you from using POST with MMRecord, but MMRecord isn't a REST client library - its a Core Data response serialization library which is networking library agnostic.

If you do need to support different HTTP methods per end point or per entity, you could consider using different MMServer subclasses per entity. Thats easy to do, since you can register one server class per core data entity in your model. That way EntityOne could use ServerOne, and EntityTwo could use ServerTwo, and each server could use GET or POST as necessary.

You can also set the server per-start request call if you really need to. Thats about as granular as you can get in terms of control.

Hi @cnstoll , thanks for the quick reply!

I'm using MMRecord as the persistent layer in my app, but due to how it works i think is more than this. The way you obtain data from any where its totally dependent on the MMServer interface and we don't have any way to customise or add options per operation/request.

Creating one subclass per entity doesn't make sense in my case, my api uses the most common http verbs for getting, updating, creating and deleting objects so every single class should be able to perform any of this types of requests.

Do you think adding an options parameter would make sense?

I didn't get that about per-start requests.

Thanks!

What you probably want to do is explore creating Manager layer in your app that performs each of the CRUD options you mentioned. In the case of obtaining data, you can use MMRecord as-is to easily serialize responses into Core Data objects. For creating objects on the server, deleting, updating, etc. I would not recommend using MMRecord. I would suggest just using AFNetworking as is.

If you're looking for a more full-featured REST framework you might want to check out RESTKit. MMRecord is intended to be very lean and focus on the simple use-case of obtaining and serializing data into application-usable objects. Its not really intended to be the backbone of your data management REST layer. You can still use it as a key piece of your overall architecture, but it shouldn't be the only part. It wont' solve all of your problems.

If you are interested in specifying a specific server per-request, all you'd have to do is call [Entity registerServer:Server]; before calling [Entity startRequest];.

  [User registerServerClass:[MMLiveServer class]];
  [User startRequestWithURN:URN
     data:nil
     context:context
     domain:self
     resultBlock:^(NSArray *records) {

     }
     failureBlock:nil];

I've worked with RESTKit for a while but it has a lot of features and the code base is really big!, this is one of the reasons i decided to start using MMRecord.

I think MMRecord solves lots of problems related to the REST data layer, it creates objects in the corresponding context after a successful POST, it merges changes after a put. Deleting object has to be done manually but i don't have problems with that.

One solution could be to create on Server per HTTP Verb and set the correct one before starting the operation ( i really don't like this solution :( ).

Where should i look for starting core data serialisation of objects by hand? This is for the case i decide to POST, PUT and DELETE objects in another place.

Thanks for the help!

The hard part of doing CRUD operations with a framework like MMRecord is knowing how to create the correct request for your needs. In essence, you need to do what MMRecord does but in reverse. That turns out to be a very hard problem to solve, which is likely part of the reason RESTKit seems so much larger - because it needs to be in order to solve that problem in a way that can be used for the majority of web services out there.

If you don't want to use RESTKit then I would suggest just writing some of the POST, PUT, DELETE logic by hand. Create requests manually using AFNetworking and composed with the bits and pieces you need from some of your model objects. This may be a lot of code, but it should be fairly easy to do.

You can certainly build on top of your implementation of MMRecord to make this easier. For example, you can write re-usable methods for returning a request dictionary representation of a model object that may be useful.

Hope that helps.

Thanks,

  • Conrad