Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Redesign Attributes/Relationships around property wrappers #38

Open
mattpolzin opened this issue Oct 2, 2019 · 5 comments
Open

Redesign Attributes/Relationships around property wrappers #38

mattpolzin opened this issue Oct 2, 2019 · 5 comments
Labels
enhancement New feature or request

Comments

@mattpolzin
Copy link
Owner

mattpolzin commented Oct 2, 2019

Exploration started here: https://github.com/mattpolzin/JSONAPI/tree/feature/transformed-property

This project is on hold until property wrapper chaining (or nesting) is supported (likely Swift 5.2).

The idea I am pursuing is to replace Attribute/TransformedAttribute with an @Attribute attribute and use an @Omittable attribute to represent when attributes can be omitted (i.e. the key is not required). I am a little less solid on relationships, but they would get similar treatment. Then, I additionally would like to flatten things so that attributes and relationships are defined in the same structure with their property attributes being the thing that differentiates them. Definitely have not worked out all of the details yet, but I hope that in addition to being a breaking change this will bring some concision and reduce the overall number of types needed a bit.

Something like

PersonProperties {
  // takes the place of current `Attribute`
  @Attribute
  var name: String

  // where age is stored as a `String` for some reason but we expect it to always be an `Int`
  // takes the place of current `TransformedAttribute`
  @Attribute(deserialize: StringToInt.self)
  var age: Int

  // takes the place of current `ToOneRelationship`
  @Relationship(to: City?.self)
  var hometown: Id?

  // takes the place of current `ToManyRelationship`
  @Relationship(to: [Person].self)
  var friends: [Id]
}
@mattpolzin mattpolzin added the enhancement New feature or request label Jan 14, 2020
@mlomeli
Copy link

mlomeli commented Sep 19, 2020

I think that's the biggest barrier of entry for new developers when adopting this library. The example code is easy to use; but understanding what's under the hood it's "advanced" Swift (maybe for me, I co-own a small developer company in Mexico, so I don't get the luxury to specialize in any language) and implementing this code was a little daunting for me.

Also you end up working with objects that are not what you usually are accustomed to. PropertyWrappers make the code more readable, and people don't really need to understand how they do things to use them.

If we could go from this

let name = person.attributes.name.value

to

let name = person.name

I bet adoption of this library would go through the roof.

@mattpolzin
Copy link
Owner Author

I do still want to explore using Property Wrappers or even Function Builders for this library. Function Builders especially could be cool, but they are only now gaining some of their more useful features (from an API development perspective) and even at that they aren't officially part of the language just yet.

@mlomeli :

...
If we could go from this
let name = person.attributes.name.value
to
let name = person.name
...

Specifically this point seems to be looking for something that this library does already offer via dynamic callable. Are you getting an error when you write let name = person.name (to use your example)? That should be equivalent to writing let name = person.attribute.name.value unless there's ambiguity the compiler can't sort out.

@mlomeli
Copy link

mlomeli commented Sep 19, 2020

Sweet! Just tested it. No, I don't get an error. I just didn't know you could call it like that. Even though it's right there in the Examples. Guess I'm over-reliant on autocomplete.

Thanks!

@reshadf
Copy link

reshadf commented Dec 4, 2023

Hi @mattpolzin is it possible to use Swift Macros to remove a lot of types and boilerplate code already? I was thinking something like being able to do the following:

@JSONAPIResource
struct Person { 

@Attribute("name") var name: String
@ToOne("house") var house: House
@ToMany("siblings") var siblings [Person]
}

I haven't looked into them already but from what I understood this could be achieved. Would love to hear your thoughts

@mattpolzin
Copy link
Owner Author

I suspect that macros could be very useful here. I haven’t been coding in Swift enough lately to have found the time to get up to speed on Swift Macros, though.

The tricky thing would be maintaining the “soul” of this JSON:API library while also adopting a new tech like property wrappers or macros. That’s pretty vague, but maybe it makes some sense?

In short, I’d be excited to see boilerplate reduced and I’d be excited to see mundane developer tasks automated as long as the library stayed codable, type safe, declarative, etc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

3 participants