Add playground page showing off sparse fieldset encoding

This commit is contained in:
Mathew Polzin
2019-08-05 17:59:38 -07:00
parent 045e88f4d4
commit 3a60ac5fe2
4 changed files with 88 additions and 1 deletions
@@ -0,0 +1,72 @@
import JSONAPI
import Foundation
// MARK: - Resource Object
enum ThingWithPropertiesDescription: JSONAPI.ResourceObjectDescription {
static let jsonType: String = "thing"
//
// NOTE: `JSONAPI.SparsableAttributes` as opposed to `JSONAPI.Attributes`
//
struct Attributes: JSONAPI.SparsableAttributes {
let stringThing: Attribute<String>
let numberThing: Attribute<Double>
let boolThing: Attribute<Bool?>
//
// NOTE: Special implementation of `CodingKeys`
//
enum CodingKeys: String, JSONAPI.SparsableCodingKey {
case stringThing
case numberThing
case boolThing
}
}
typealias Relationships = NoRelationships
}
typealias ThingWithProperties = JSONAPI.ResourceObject<ThingWithPropertiesDescription, NoMetadata, NoLinks, String>
// MARK: - Document
//
// NOTE: Using `JSONAPI.EncodableResourceBody` which means the document type will be `Encodable` but not `Decodable`.
//
typealias Document<PrimaryResourceBody: JSONAPI.EncodableResourceBody, IncludeType: JSONAPI.Include> = JSONAPI.Document<PrimaryResourceBody, NoMetadata, NoLinks, IncludeType, NoAPIDescription, UnknownJSONAPIError>
//
// NOTE: Using `JSONAPI.EncodablePrimaryResource` which means the `ResourceBody` will be `Encodable` but not `Decodable.
//
typealias SingleDocument<T: JSONAPI.EncodablePrimaryResource> = Document<SingleResourceBody<T>, NoIncludes>
// MARK: - Resource Initialization
let resource = ThingWithProperties(id: .init(rawValue: "1234"),
attributes: .init(stringThing: .init(value: "hello world"),
numberThing: .init(value: 10),
boolThing: .init(value: nil)),
relationships: .none,
meta: .none,
links: .none)
//
// NOTE: Creating a sparse resource that will only encode
// the attribute named "stringThing"
//
let sparseResource = resource.sparse(with: [.stringThing])
// MARK: - Encoding
let encoder = JSONEncoder()
let sparseResourceDoc = SingleDocument(apiDescription: .none,
body: .init(resourceObject: sparseResource),
includes: .none,
meta: .none,
links: .none)
let data = try! encoder.encode(sparseResourceDoc)
print(String(data: data, encoding: .utf8)!)
@@ -8,6 +8,7 @@ Please enjoy these examples, but allow me the forced casting and the lack of err
********/
// MARK: - Create a request or response body with one Dog in it
let dogFromCode = try! Dog(name: "Buddy", owner: nil)
@@ -15,17 +16,20 @@ let singleDogDocument = SingleDogDocument(apiDescription: .none, body: .init(res
let singleDogData = try! JSONEncoder().encode(singleDogDocument)
// MARK: - Parse a request or response body with one Dog in it
let dogResponse = try! JSONDecoder().decode(SingleDogDocument.self, from: singleDogData)
let dogFromData = dogResponse.body.primaryResource?.value
let dogOwner: Person.Identifier? = dogFromData.flatMap { $0 ~> \.owner }
// MARKL - Parse a request or response body with one Dog in it using an alternative model
// MARK: - Parse a request or response body with one Dog in it using an alternative model
typealias AltSingleDogDocument = JSONAPI.Document<SingleResourceBody<AlternativeDog>, NoMetadata, NoLinks, NoIncludes, NoAPIDescription, UnknownJSONAPIError>
let altDogResponse = try! JSONDecoder().decode(AltSingleDogDocument.self, from: singleDogData)
let altDogFromData = altDogResponse.body.primaryResource?.value
let altDogHuman: Person.Identifier? = altDogFromData.flatMap { $0 ~> \.human }
// MARK: - Create a request or response with multiple people and dogs and houses included
let personIds = [Person.Identifier(), Person.Identifier()]
let dogs = try! [Dog(name: "Buddy", owner: personIds[0]), Dog(name: "Joy", owner: personIds[0]), Dog(name: "Travis", owner: personIds[1])]
@@ -36,6 +40,7 @@ let includes = dogs.map { BatchPeopleDocument.Include($0) } + houses.map { Batch
let batchPeopleDocument = BatchPeopleDocument(apiDescription: .none, body: .init(resourceObjects: people), includes: .init(values: includes), meta: .none, links: .none)
let batchPeopleData = try! JSONEncoder().encode(batchPeopleDocument)
// MARK: - Parse a request or response body with multiple people in it and dogs and houses included
let peopleResponse = try! JSONDecoder().decode(BatchPeopleDocument.self, from: batchPeopleData)
@@ -47,6 +52,7 @@ print("-----")
print(peopleResponse)
print("-----")
// MARK: - Pass successfully parsed body to other parts of the code
/*
@@ -59,6 +65,7 @@ if case let .data(bodyData) = peopleResponse.body {
}
*/
// MARK: - Work in the abstract
func process<T: JSONAPIDocument>(document: T) {
+1
View File
@@ -5,5 +5,6 @@
<page name='Usage'/>
<page name='Full Client &amp; Server Example'/>
<page name='Full Document Verbose Generation'/>
<page name='Sparse Fieldsets Example'/>
</pages>
</playground>
+7
View File
@@ -144,6 +144,10 @@ extension DocumentTests {
("test_singleDocumentSomeIncludesWithMetadata_encode", test_singleDocumentSomeIncludesWithMetadata_encode),
("test_singleDocumentSomeIncludesWithMetadataWithAPIDescription", test_singleDocumentSomeIncludesWithMetadataWithAPIDescription),
("test_singleDocumentSomeIncludesWithMetadataWithAPIDescription_encode", test_singleDocumentSomeIncludesWithMetadataWithAPIDescription_encode),
("test_sparseIncludeFullPrimaryResource", test_sparseIncludeFullPrimaryResource),
("test_sparseIncludeSparsePrimaryResource", test_sparseIncludeSparsePrimaryResource),
("test_sparsePrimaryResource", test_sparsePrimaryResource),
("test_sparsePrimaryResourceOptionalAndNil", test_sparsePrimaryResourceOptionalAndNil),
("test_unknownErrorDocumentAddIncludes", test_unknownErrorDocumentAddIncludes),
("test_unknownErrorDocumentAddIncludingType", test_unknownErrorDocumentAddIncludingType),
("test_unknownErrorDocumentMissingLinks", test_unknownErrorDocumentMissingLinks),
@@ -275,6 +279,7 @@ extension IncludedTests {
// to regenerate.
static let __allTests__IncludedTests = [
("test_appending", test_appending),
("test_ComboSparseAndFullIncludeTypes", test_ComboSparseAndFullIncludeTypes),
("test_EightDifferentIncludes", test_EightDifferentIncludes),
("test_EightDifferentIncludes_encode", test_EightDifferentIncludes_encode),
("test_FiveDifferentIncludes", test_FiveDifferentIncludes),
@@ -285,6 +290,7 @@ extension IncludedTests {
("test_NineDifferentIncludes_encode", test_NineDifferentIncludes_encode),
("test_OneInclude", test_OneInclude),
("test_OneInclude_encode", test_OneInclude_encode),
("test_OneSparseIncludeType", test_OneSparseIncludeType),
("test_SevenDifferentIncludes", test_SevenDifferentIncludes),
("test_SevenDifferentIncludes_encode", test_SevenDifferentIncludes_encode),
("test_SixDifferentIncludes", test_SixDifferentIncludes),
@@ -295,6 +301,7 @@ extension IncludedTests {
("test_TwoDifferentIncludes_encode", test_TwoDifferentIncludes_encode),
("test_TwoSameIncludes", test_TwoSameIncludes),
("test_TwoSameIncludes_encode", test_TwoSameIncludes_encode),
("test_TwoSparseIncludeTypes", test_TwoSparseIncludeTypes),
("test_zeroIncludes", test_zeroIncludes),
("test_zeroIncludes_encode", test_zeroIncludes_encode),
("test_zeroIncludes_init", test_zeroIncludes_init),