diff --git a/JSONAPI.playground/Pages/Usage.xcplaygroundpage/Contents.swift b/JSONAPI.playground/Pages/Usage.xcplaygroundpage/Contents.swift index 12542d6..ac259aa 100644 --- a/JSONAPI.playground/Pages/Usage.xcplaygroundpage/Contents.swift +++ b/JSONAPI.playground/Pages/Usage.xcplaygroundpage/Contents.swift @@ -44,6 +44,7 @@ let housesFromData = peopleResponse.body.includes?[House.self] if case let .data(bodyData) = peopleResponse.body { print(bodyData) + print("first person's name: \(bodyData.primary.values[0][\.fullName])") } else { print("no body data") } diff --git a/JSONAPI.playground/Sources/Entities.swift b/JSONAPI.playground/Sources/Entities.swift index 2ad13b2..025abaa 100644 --- a/JSONAPI.playground/Sources/Entities.swift +++ b/JSONAPI.playground/Sources/Entities.swift @@ -35,6 +35,10 @@ public enum PersonDescription: EntityDescription { public let name: Attribute<[String]> public let favoriteColor: Attribute + public var fullName: Attribute { + return name.map { $0.joined(separator: " ") } + } + public init(name: Attribute<[String]>, favoriteColor: Attribute) { self.name = name self.favoriteColor = favoriteColor diff --git a/README.md b/README.md index cf8631e..c2a9013 100644 --- a/README.md +++ b/README.md @@ -100,7 +100,7 @@ To create an Xcode project for JSONAPI, run - [x] Roll my own `Result` or find an alternative that doesn't use `Foundation`. - [ ] Create more descriptive errors that are easier to use for troubleshooting. - [x] Make it easier to construct `Attributes` and `Relationships` values in test cases (literal expressibility). -- [ ] Make `TransformedAttribute` a Monad (or at least a Functor). +- [x] Make `TransformedAttribute` a Functor. ## Usage @@ -257,6 +257,16 @@ Note that the first generic parameter of `TransformAttribute` is the type you ex You can also creator `Validator`s and `ValidatedAttribute`s. A `Validator` is just a `Transformer` that by convention does not perform a transformation. It simply `throws` if an attribute value is invalid. +#### Computed `Attribute` + +You can add computed properties to your `EntityDescription.Attributes` struct if you would like to expose attributes that are not explicitly represented by the JSON. These computed properties should still have the type `Attribute` because that way you can take advantage of the quick access provided by `Entity`'s subscript operator. Here's an example of how you might take the `Person[\.name]` attribute from the example above and create a `fullName` computed property. + +``` +public var fullName: Attribute { + return name.map { $0.joined(separator: " ") } +} +``` + ### `JSONAPIDocument` The entirety of a JSON API request or response is encoded or decoded from- or to a `JSONAPIDocument`. As an example, a JSON API response containing one `Person` and no included entities could be decoded as follows: