mattpolzin / JSONAPI

Swift Codable JSON:API framework
MIT License
75 stars 19 forks source link

Update Documentation: PATCH/Encode to server #40

Closed Xal3ph closed 5 years ago

Xal3ph commented 5 years ago

The majority of our data we receive will be read-only, such an immutable solution is ideal. However, there are several cases where we need to create a new Resource, add data from a user input and submit it to the server in the JSONAPI format. I'm delighted that you are using Codable (Encodable/Decodable) as it connects to Alamofire very easily with the responseDecodable method.

An example that could be helpful is: Pulling back a dog from the server which have existing attributes (or null) (pseudocode) Decoding to Resource<DogDescription> Modifying Dog.name and Dog.dateOfBirth attributes Encoding to Resource<DogDescription> Submitting to the server (pseudocode)

Thank you in advance for your response and patience! Looking forward to the redesign you mentioned.

mattpolzin commented 5 years ago

This is a great idea for me to think through. As you noticed, I designed the library around immutability because the vast majority of my own use-cases are either to retrieve a resource from the server and use it or create an entirely new resource as the client and then send it to the server. Thinking through a receive, mutate, send example might point to some places I made suboptimal choices with the API.

I'll try to come up with a relatively easy solution given the current library and also think on ways to improve the experience in a future version.

mattpolzin commented 5 years ago

I'll be rolling some improvements around this into a future release, but here is what I came up with first (you can snag the extension here and use it in your codebase if it works for you): https://github.com/mattpolzin/JSONAPI/blob/master/JSONAPI.playground/Pages/PATCHing.xcplaygroundpage/Contents.swift

EDIT: "map" does not feel like the most appropriate word here to me because the Attributes type is not changing, just its values. When I update the library I may choose a word that feels more appropriate for what is going on.

mattpolzin commented 5 years ago

I am going to introduce the above-linked functions as replacingAttributes() and replacingRelationships() because

  1. map feels misplaced given the inability (and really disinterest in-) changing the types of the Attributes or Relationships.
  2. tap feels a bit confusing given the inability to modify the ResourceObject itself and a tap pattern really only saves lines with Attributes types containing var properties.
mattpolzin commented 5 years ago

Decided to add both replacing and tapping because the latter is so much more concise when working with Attributes or Relationships that have mutable properties.

Assuming DogDescription has

struct Attributes: JSONAPI.Attributes { 
  var name: Attribute<String>
  var dateOfBirth: Attribute<Date>
}

Something like the following would update both:

let updatedDog = originalDog
  .tappingAttributes { attributes in
    attributes.name = .init(value: "Charlie")
    attributes.dateOfBirth = .init(value: Date())
}

Full example forthcoming.

mattpolzin commented 5 years ago

Example written: https://colab.research.google.com/drive/16KY-0BoLQKiSUh9G7nYmHzB8b2vhXA2U

seifscape commented 5 years ago

Thank you @mattpolzin so much for your quick response and help!

Xal3ph commented 5 years ago

That's perfect, thank you!