From 8f9ec11f270734309b3441c0eaf8d1206763fe9a Mon Sep 17 00:00:00 2001 From: Mathew Polzin Date: Wed, 14 Aug 2019 08:57:57 -0700 Subject: [PATCH 1/3] Housekeeping in the README --- README.md | 58 ++++++++++++++++++++----------------------------------- 1 file changed, 21 insertions(+), 37 deletions(-) diff --git a/README.md b/README.md index 7a128bc..ff5baeb 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ A Swift package for encoding to- and decoding from **JSON API** compliant reques See the JSON API Spec here: https://jsonapi.org/format/ -:warning: Although I find the type-safety of this framework appealing, the Swift compiler currently has enough trouble with it that it can become difficult to reason about errors produced by small typos. Similarly, auto-complete fails to provide reasonable suggestions much of the time. If you get the code right, everything compiles, otherwise it can suck to figure out what is wrong. This is mostly a concern when creating resource objects in-code (servers and test suites must do this). Writing a client that uses this framework to ingest JSON API Compliant API responses is much less painful. :warning: +:warning: This library provides well-tested type safety when working with JSON:API 1.0, however the Swift compiler can sometimes have difficulty tracking down small typos when initializing `ResourceObjects`. Once the code is written correctly, it will compile, but tracking down the source of programmer errors can be an annoyance. This is mostly a concern when creating resource objects in-code (servers and test cases must do this). Writing a client that uses this framework to ingest JSON API Compliant API responses is much less painful. :warning: ## Table of Contents @@ -109,52 +109,34 @@ Note that Playground support for importing non-system Frameworks is still a bit ### JSON:API #### Document -- `data` - - [x] Encoding/Decoding -- `included` - - [x] Encoding/Decoding -- `errors` - - [x] Encoding/Decoding -- `meta` - - [x] Encoding/Decoding -- `jsonapi` (i.e. API Information) - - [x] Encoding/Decoding -- `links` - - [x] Encoding/Decoding +- [x] `data` +- [x] `included` +- [x] `errors` +- [x] `meta` +- [x] `jsonapi` (i.e. API Information) +- [x] `links` #### Resource Object -- `id` - - [x] Encoding/Decoding -- `type` - - [x] Encoding/Decoding -- `attributes` - - [x] Encoding/Decoding -- `relationships` - - [x] Encoding/Decoding -- `links` - - [x] Encoding/Decoding -- `meta` - - [x] Encoding/Decoding +- [x] `id` +- [x] `type` +- [x] `attributes` +- [x] `relationships` +- [x] `links` +- [x] `meta` #### Relationship Object -- `data` - - [x] Encoding/Decoding -- `links` - - [x] Encoding/Decoding -- `meta` - - [x] Encoding/Decoding +- [x] `data` +- [x] `links` +- [x] `meta` #### Links Object -- `href` - - [x] Encoding/Decoding -- `meta` - - [x] Encoding/Decoding +- [x] `href` +- [x] `meta` ### Misc - [x] Support transforms on `Attributes` values (e.g. to support different representations of `Date`) - [x] Support validation on `Attributes`. -- [x] Support sparse fieldsets (encoding only). A client can likely just define a new model to represent a sparse population of another model in a very specific use case. On the server side, sparse fieldsets of Resource Objects can be encoded without creating one model for every possible sparse fieldset. -- [ ] Create more descriptive errors that are easier to use for troubleshooting. +- [x] Support sparse fieldsets (encoding only). A client can likely just define a new model to represent a sparse population of another model in a very specific use case for decoding purposes. On the server side, sparse fieldsets of Resource Objects can be encoded without creating one model for every possible sparse fieldset. ### Testing #### Resource Object Validator @@ -163,6 +145,8 @@ Note that Playground support for importing non-system Frameworks is still a bit - [x] Only allow `ToManyRelationship` and `ToOneRelationship` within `Relationships` struct. ### Potential Improvements +These ideas could be implemented in future versions. + - [ ] (Maybe) Use `KeyPath` to specify `Includes` thus creating type safety around the relationship between a primary resource type and the types of included resources. - [ ] (Maybe) Replace `SingleResourceBody` and `ManyResourceBody` with support at the `Document` level to just interpret `PrimaryResource`, `PrimaryResource?`, or `[PrimaryResource]` as the same decoding/encoding strategies. - [ ] Support sideposting. JSONAPI spec might become opinionated in the future (https://github.com/json-api/json-api/pull/1197, https://github.com/json-api/json-api/issues/1215, https://github.com/json-api/json-api/issues/1216) but there is also an existing implementation to consider (https://jsonapi-suite.github.io/jsonapi_suite/ruby/writes/nested-writes). At this time, any sidepost implementation would be an awesome tertiary library to be used alongside the primary JSONAPI library. Maybe `JSONAPISideloading`. From 86a9345fdd2f85d67d6338045628664663d18346 Mon Sep 17 00:00:00 2001 From: Mathew Polzin Date: Wed, 14 Aug 2019 09:22:06 -0700 Subject: [PATCH 2/3] Adding some documentation and making SparseFieldEncoder internal because it does not need to be public. --- Sources/JSONAPI/Document/Document.swift | 4 ++++ Sources/JSONAPI/Document/Includes.swift | 10 ++++++++++ Sources/JSONAPI/Document/ResourceBody.swift | 4 ++++ Sources/JSONAPI/Resource/Id.swift | 3 +++ Sources/JSONAPI/SparseFields/SparseFieldEncoder.swift | 4 ++-- .../SparseFields/SparseFieldEncoderTests.swift | 2 +- 6 files changed, 24 insertions(+), 3 deletions(-) diff --git a/Sources/JSONAPI/Document/Document.swift b/Sources/JSONAPI/Document/Document.swift index caad138..aedb87a 100644 --- a/Sources/JSONAPI/Document/Document.swift +++ b/Sources/JSONAPI/Document/Document.swift @@ -53,7 +53,9 @@ public struct Document public let meta: MetaType public let links: LinksType @@ -66,6 +68,8 @@ public struct Document> = ...` +/// +/// then you can access all `Thing1` included resources with +/// +/// `let includedThings = includes[Thing1.self]` public struct Includes: Encodable, Equatable { public static var none: Includes { return .init(values: []) } diff --git a/Sources/JSONAPI/Document/ResourceBody.swift b/Sources/JSONAPI/Document/ResourceBody.swift index 4dbac87..3fdef10 100644 --- a/Sources/JSONAPI/Document/ResourceBody.swift +++ b/Sources/JSONAPI/Document/ResourceBody.swift @@ -48,6 +48,9 @@ public func +(_ left: R, right: R) -> R { return left.appending(right) } +/// A type allowing for a document body containing 1 primary resource. +/// If the `Entity` specialization is an `Optional` type, the body can contain +/// 0 or 1 primary resources. public struct SingleResourceBody: EncodableResourceBody { public let value: Entity @@ -56,6 +59,7 @@ public struct SingleResourceBody: EncodableResourceBody, Appendable { public let values: [Entity] diff --git a/Sources/JSONAPI/Resource/Id.swift b/Sources/JSONAPI/Resource/Id.swift index 7265a18..a375c08 100644 --- a/Sources/JSONAPI/Resource/Id.swift +++ b/Sources/JSONAPI/Resource/Id.swift @@ -28,6 +28,9 @@ public protocol CreatableRawIdType: RawIdType { extension String: RawIdType {} +/// A type that can be used as the `MaybeRawId` for a `ResourceObject` that does not +/// have an Id (most likely because it was created by a client and the server will be responsible +/// for assigning it an Id). public struct Unidentified: MaybeRawId, CustomStringConvertible { public init() {} diff --git a/Sources/JSONAPI/SparseFields/SparseFieldEncoder.swift b/Sources/JSONAPI/SparseFields/SparseFieldEncoder.swift index a377fc9..36a1a95 100644 --- a/Sources/JSONAPI/SparseFields/SparseFieldEncoder.swift +++ b/Sources/JSONAPI/SparseFields/SparseFieldEncoder.swift @@ -5,7 +5,7 @@ // Created by Mathew Polzin on 8/4/19. // -public class SparseFieldEncoder: Encoder { +class SparseFieldEncoder: Encoder { private let wrappedEncoder: Encoder private let allowedKeys: [SparseKey] @@ -37,7 +37,7 @@ public class SparseFieldEncoder: Encoder { } } -public struct SparseFieldKeyedEncodingContainer: KeyedEncodingContainerProtocol where SparseKey: CodingKey, SparseKey: Equatable, Key: CodingKey { +struct SparseFieldKeyedEncodingContainer: KeyedEncodingContainerProtocol where SparseKey: CodingKey, SparseKey: Equatable, Key: CodingKey { private var wrappedContainer: KeyedEncodingContainer private let allowedKeys: [SparseKey] diff --git a/Tests/JSONAPITests/SparseFields/SparseFieldEncoderTests.swift b/Tests/JSONAPITests/SparseFields/SparseFieldEncoderTests.swift index f0abce2..c6192f8 100644 --- a/Tests/JSONAPITests/SparseFields/SparseFieldEncoderTests.swift +++ b/Tests/JSONAPITests/SparseFields/SparseFieldEncoderTests.swift @@ -6,7 +6,7 @@ // import XCTest -import JSONAPI +@testable import JSONAPI import Foundation class SparseFieldEncoderTests: XCTestCase { From 89217f7187e9118d988f921325015addcfb870bc Mon Sep 17 00:00:00 2001 From: Mathew Polzin Date: Wed, 14 Aug 2019 17:31:43 -0700 Subject: [PATCH 3/3] bump podspec version --- JSONAPI.podspec | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/JSONAPI.podspec b/JSONAPI.podspec index d884b6c..615b1c1 100644 --- a/JSONAPI.podspec +++ b/JSONAPI.podspec @@ -16,7 +16,7 @@ Pod::Spec.new do |spec| # spec.name = "JSONAPI" - spec.version = "0.31.1" + spec.version = "1.0.0" spec.summary = "Swift Codable JSON API framework." # This description is used to generate tags and improve search results.