Add a bit more flavor to Examples.swift

This commit is contained in:
Mathew Polzin
2018-11-15 23:35:23 -08:00
parent 1158bb8acd
commit 2ae92cf33f
2 changed files with 64 additions and 10 deletions
+55 -1
View File
@@ -5,8 +5,20 @@
// Created by Mathew Polzin on 11/12/18.
//
import Foundation
import JSONAPI
/*******
Please enjoy these examples, but allow me the lack of error checking and forced casting for the sake of brevity.
********/
typealias ExampleEntity<Description: EntityDescription> = Entity<Description, Id<String, Description>>
// MARK: - A few resource objects (entities)
enum PersonDescription: EntityDescription {
static var type: String { return "people" }
@@ -18,7 +30,49 @@ enum PersonDescription: EntityDescription {
struct Relationships: JSONAPI.Relationships {
let friends: ToManyRelationship<Person>
let dogs: ToManyRelationship<Dog>
let home: ToOneRelationship<House>
}
}
typealias Person = Entity<PersonDescription, Id<String, PersonDescription>>
typealias Person = ExampleEntity<PersonDescription>
enum DogDescription: EntityDescription {
static var type: String { return "dogs" }
struct Attributes: JSONAPI.Attributes {
let name: String
}
struct Relationships: JSONAPI.Relationships {
let owner: ToOneRelationship<Person?>
}
}
typealias Dog = ExampleEntity<DogDescription>
enum HouseDescription: EntityDescription {
static var type: String { return "houses" }
typealias Attributes = NoAttributes
typealias Relationships = NoRelatives
}
typealias House = ExampleEntity<HouseDescription>
// MARK: - Parse a response body with one Dog in it
typealias SingleDogResponse = JSONAPIDocument<SingleResourceBody<Dog>, NoIncludes, BasicJSONAPIError>
let dummyData = "".data(using: .utf8)!
let dogResponse = try! JSONDecoder().decode(SingleDogResponse.self, from: dummyData)
let dog = dogResponse.body.data?.primary.value
// MARK: Parse a response body with multiple people in it and dogs and houses included
typealias BatchPeopleResponse = JSONAPIDocument<ManyResourceBody<Person>, Include2<Dog, House>, BasicJSONAPIError>
let peopleResponse = try! JSONDecoder().decode(BatchPeopleResponse.self, from: dummyData)
let people = peopleResponse.body.data?.primary.values
let dogs = peopleResponse.body.data?.included[Dog.self]
let houses = peopleResponse.body.data?.included[House.self]
+9 -9
View File
@@ -12,24 +12,24 @@
/// API uses snake case, you will want to use
/// a conversion such as the one offerred by the
/// Foundation JSONEncoder/Decoder: `KeyDecodingStrategy`
public struct JSONAPIDocument<Body: ResourceBody, Include: IncludeDecoder, Error: JSONAPIError & Decodable> {
public let body: Data
public struct JSONAPIDocument<ResourceBody: JSONAPI.ResourceBody, Include: IncludeDecoder, Error: JSONAPIError & Decodable> {
public let body: Body
// public let meta: Meta?
// public let jsonApi: APIDescription?
// public let links: Links?
public enum Data {
public enum Body {
case errors([Error])
case data(Body, included: Includes<Include>)
case data(primary: ResourceBody, included: Includes<Include>)
public var isError: Bool {
guard case .errors = self else { return false }
return true
}
public var data: (Body, included: Includes<Include>)? {
guard case let .data(body, included: includes) = self else { return nil }
return (body, included: includes)
public var data: (primary: ResourceBody, included: Includes<Include>)? {
guard case let .data(primary: body, included: includes) = self else { return nil }
return (primary: body, included: includes)
}
}
}
@@ -47,7 +47,7 @@ extension JSONAPIDocument: Decodable {
public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: RootCodingKeys.self)
let maybeData = try container.decodeIfPresent(Body.self, forKey: .data)
let maybeData = try container.decodeIfPresent(ResourceBody.self, forKey: .data)
let maybeIncludes = try container.decodeIfPresent(Includes<Include>.self, forKey: .included)
let errors = try container.decodeIfPresent([Error].self, forKey: .errors)
@@ -66,6 +66,6 @@ extension JSONAPIDocument: Decodable {
return
}
body = .data(data, included: maybeIncludes ?? Includes<Include>.none)
body = .data(primary: data, included: maybeIncludes ?? Includes<Include>.none)
}
}