mirror of
https://github.com/encounter/JSONAPI.git
synced 2026-07-10 12:18:40 -07:00
Compare commits
7 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 44f9bca7dc | |||
| 774b53b9b6 | |||
| 654d3bfd2b | |||
| c26d6d99c0 | |||
| 43dcc4fb12 | |||
| abae975f59 | |||
| 0e6b2a7771 |
+2
-2
@@ -16,7 +16,7 @@ Pod::Spec.new do |spec|
|
|||||||
#
|
#
|
||||||
|
|
||||||
spec.name = "MP-JSONAPI"
|
spec.name = "MP-JSONAPI"
|
||||||
spec.version = "2.2.0"
|
spec.version = "2.3.0"
|
||||||
spec.summary = "Swift Codable JSON API framework."
|
spec.summary = "Swift Codable JSON API framework."
|
||||||
|
|
||||||
# This description is used to generate tags and improve search results.
|
# This description is used to generate tags and improve search results.
|
||||||
@@ -136,6 +136,6 @@ See the JSON API Spec here: https://jsonapi.org/format/
|
|||||||
# spec.requires_arc = true
|
# spec.requires_arc = true
|
||||||
|
|
||||||
# spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
|
# spec.xcconfig = { "HEADER_SEARCH_PATHS" => "$(SDKROOT)/usr/include/libxml2" }
|
||||||
spec.dependency "Poly", "~> 2.1"
|
spec.dependency "Poly", "~> 2.2"
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
+2
-2
@@ -6,8 +6,8 @@
|
|||||||
"repositoryURL": "https://github.com/mattpolzin/Poly.git",
|
"repositoryURL": "https://github.com/mattpolzin/Poly.git",
|
||||||
"state": {
|
"state": {
|
||||||
"branch": null,
|
"branch": null,
|
||||||
"revision": "4a08517b24f8e9f6dd8c02ec7da316aac5c00e2e",
|
"revision": "b24fd3b41bf3126d4c6dede3708135182172af60",
|
||||||
"version": "2.1.0"
|
"version": "2.2.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
+1
-1
@@ -18,7 +18,7 @@ let package = Package(
|
|||||||
targets: ["JSONAPITesting"])
|
targets: ["JSONAPITesting"])
|
||||||
],
|
],
|
||||||
dependencies: [
|
dependencies: [
|
||||||
.package(url: "https://github.com/mattpolzin/Poly.git", .upToNextMajor(from: "2.1.0")),
|
.package(url: "https://github.com/mattpolzin/Poly.git", .upToNextMajor(from: "2.2.0")),
|
||||||
],
|
],
|
||||||
targets: [
|
targets: [
|
||||||
.target(
|
.target(
|
||||||
|
|||||||
@@ -5,15 +5,17 @@ A Swift package for encoding to- and decoding from **JSON API** compliant reques
|
|||||||
|
|
||||||
See the JSON API Spec here: https://jsonapi.org/format/
|
See the JSON API Spec here: https://jsonapi.org/format/
|
||||||
|
|
||||||
: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:
|
: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.
|
||||||
|
|
||||||
## Quick Start
|
## Quick Start
|
||||||
|
|
||||||
|
:warning: The following Google Colab examples have correct code, but there appears to be an bug in the branch of the Swift compiler currently being used by the Google Colab Swift notebooks such that the `JSONAPI` package cannot be pulled in and you cannot run the examples in-browser.
|
||||||
|
|
||||||
### Clientside
|
### Clientside
|
||||||
- [Basic Example](https://colab.research.google.com/drive/1IS7lRSBGoiW02Vd1nN_rfdDbZvTDj6Te)
|
- [Basic Example](https://colab.research.google.com/drive/1IS7lRSBGoiW02Vd1nN_rfdDbZvTDj6Te)
|
||||||
- [Compound Example](https://colab.research.google.com/drive/1BdF0Kc7l2ixDfBZEL16FY6palweDszQU)
|
- [Compound Example](https://colab.research.google.com/drive/1BdF0Kc7l2ixDfBZEL16FY6palweDszQU)
|
||||||
- [Metadata Example](https://colab.research.google.com/drive/10dEESwiE9I3YoyfzVeOVwOKUTEgLT3qr)
|
- [Metadata Example](https://colab.research.google.com/drive/10dEESwiE9I3YoyfzVeOVwOKUTEgLT3qr)
|
||||||
- [Errors Example](https://colab.research.google.com/drive/1TIv6STzlHrkTf_-9Eu8sv8NoaxhZcFZH)
|
- [Custom Errors Example](https://colab.research.google.com/drive/1TIv6STzlHrkTf_-9Eu8sv8NoaxhZcFZH)
|
||||||
|
|
||||||
### Serverside
|
### Serverside
|
||||||
- [GET Example](https://colab.research.google.com/drive/1krbhzSfz8mwkBTQQnKUZJLEtYsJKSfYX)
|
- [GET Example](https://colab.research.google.com/drive/1krbhzSfz8mwkBTQQnKUZJLEtYsJKSfYX)
|
||||||
|
|||||||
@@ -169,3 +169,11 @@ extension Includes where I: _Poly10 {
|
|||||||
return values.compactMap { $0.j }
|
return values.compactMap { $0.j }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// MARK: - 11 includes
|
||||||
|
public typealias Include11 = Poly11
|
||||||
|
extension Includes where I: _Poly11 {
|
||||||
|
public subscript(_ lookup: I.K.Type) -> [I.K] {
|
||||||
|
return values.compactMap { $0.k }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// BasicError.swift
|
// BasicJSONAPIError.swift
|
||||||
// JSONAPI
|
// JSONAPI
|
||||||
//
|
//
|
||||||
// Created by Mathew Polzin on 9/29/19.
|
// Created by Mathew Polzin on 9/29/19.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// GenericError.swift
|
// GenericJSONAPIError.swift
|
||||||
// JSONAPI
|
// JSONAPI
|
||||||
//
|
//
|
||||||
// Created by Mathew Polzin on 9/29/19.
|
// Created by Mathew Polzin on 9/29/19.
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
//
|
//
|
||||||
// Error.swift
|
// JSONAPIError.swift
|
||||||
// JSONAPI
|
// JSONAPI
|
||||||
//
|
//
|
||||||
// Created by Mathew Polzin on 11/10/18.
|
// Created by Mathew Polzin on 11/10/18.
|
||||||
|
|||||||
@@ -79,3 +79,8 @@ extension Poly9: PrimaryResource, OptionalPrimaryResource where A: PolyWrapped,
|
|||||||
extension Poly10: EncodablePrimaryResource, OptionalEncodablePrimaryResource where A: EncodablePolyWrapped, B: EncodablePolyWrapped, C: EncodablePolyWrapped, D: EncodablePolyWrapped, E: EncodablePolyWrapped, F: EncodablePolyWrapped, G: EncodablePolyWrapped, H: EncodablePolyWrapped, I: EncodablePolyWrapped, J: EncodablePolyWrapped {}
|
extension Poly10: EncodablePrimaryResource, OptionalEncodablePrimaryResource where A: EncodablePolyWrapped, B: EncodablePolyWrapped, C: EncodablePolyWrapped, D: EncodablePolyWrapped, E: EncodablePolyWrapped, F: EncodablePolyWrapped, G: EncodablePolyWrapped, H: EncodablePolyWrapped, I: EncodablePolyWrapped, J: EncodablePolyWrapped {}
|
||||||
|
|
||||||
extension Poly10: PrimaryResource, OptionalPrimaryResource where A: PolyWrapped, B: PolyWrapped, C: PolyWrapped, D: PolyWrapped, E: PolyWrapped, F: PolyWrapped, G: PolyWrapped, H: PolyWrapped, I: PolyWrapped, J: PolyWrapped {}
|
extension Poly10: PrimaryResource, OptionalPrimaryResource where A: PolyWrapped, B: PolyWrapped, C: PolyWrapped, D: PolyWrapped, E: PolyWrapped, F: PolyWrapped, G: PolyWrapped, H: PolyWrapped, I: PolyWrapped, J: PolyWrapped {}
|
||||||
|
|
||||||
|
// MARK: - 11 types
|
||||||
|
extension Poly11: EncodablePrimaryResource, OptionalEncodablePrimaryResource where A: EncodablePolyWrapped, B: EncodablePolyWrapped, C: EncodablePolyWrapped, D: EncodablePolyWrapped, E: EncodablePolyWrapped, F: EncodablePolyWrapped, G: EncodablePolyWrapped, H: EncodablePolyWrapped, I: EncodablePolyWrapped, J: EncodablePolyWrapped, K: EncodablePolyWrapped {}
|
||||||
|
|
||||||
|
extension Poly11: PrimaryResource, OptionalPrimaryResource where A: PolyWrapped, B: PolyWrapped, C: PolyWrapped, D: PolyWrapped, E: PolyWrapped, F: PolyWrapped, G: PolyWrapped, H: PolyWrapped, I: PolyWrapped, J: PolyWrapped, K: PolyWrapped {}
|
||||||
|
|||||||
@@ -197,6 +197,28 @@ class IncludedTests: XCTestCase {
|
|||||||
test_DecodeEncodeEquality(type: Includes<Include10<TestEntity, TestEntity2, TestEntity3, TestEntity4, TestEntity5, TestEntity6, TestEntity7, TestEntity8, TestEntity9, TestEntity10>>.self,
|
test_DecodeEncodeEquality(type: Includes<Include10<TestEntity, TestEntity2, TestEntity3, TestEntity4, TestEntity5, TestEntity6, TestEntity7, TestEntity8, TestEntity9, TestEntity10>>.self,
|
||||||
data: ten_different_type_includes)
|
data: ten_different_type_includes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func test_ElevenDifferentIncludes() {
|
||||||
|
let includes = decoded(type: Includes<Include11<TestEntity, TestEntity2, TestEntity3, TestEntity4, TestEntity5, TestEntity6, TestEntity7, TestEntity8, TestEntity9, TestEntity10, TestEntity11>>.self,
|
||||||
|
data: eleven_different_type_includes)
|
||||||
|
|
||||||
|
XCTAssertEqual(includes[TestEntity.self].count, 1)
|
||||||
|
XCTAssertEqual(includes[TestEntity2.self].count, 1)
|
||||||
|
XCTAssertEqual(includes[TestEntity3.self].count, 1)
|
||||||
|
XCTAssertEqual(includes[TestEntity4.self].count, 1)
|
||||||
|
XCTAssertEqual(includes[TestEntity5.self].count, 1)
|
||||||
|
XCTAssertEqual(includes[TestEntity6.self].count, 1)
|
||||||
|
XCTAssertEqual(includes[TestEntity7.self].count, 1)
|
||||||
|
XCTAssertEqual(includes[TestEntity8.self].count, 1)
|
||||||
|
XCTAssertEqual(includes[TestEntity9.self].count, 1)
|
||||||
|
XCTAssertEqual(includes[TestEntity10.self].count, 1)
|
||||||
|
XCTAssertEqual(includes[TestEntity11.self].count, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
func test_ElevenDifferentIncludes_encode() {
|
||||||
|
test_DecodeEncodeEquality(type: Includes<Include11<TestEntity, TestEntity2, TestEntity3, TestEntity4, TestEntity5, TestEntity6, TestEntity7, TestEntity8, TestEntity9, TestEntity10, TestEntity11>>.self,
|
||||||
|
data: eleven_different_type_includes)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: - Appending
|
// MARK: - Appending
|
||||||
@@ -503,4 +525,15 @@ extension IncludedTests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
typealias TestEntity10 = BasicEntity<TestEntityType10>
|
typealias TestEntity10 = BasicEntity<TestEntityType10>
|
||||||
|
|
||||||
|
enum TestEntityType11: ResourceObjectDescription {
|
||||||
|
|
||||||
|
typealias Attributes = NoAttributes
|
||||||
|
|
||||||
|
public static var jsonType: String { return "test_entity11" }
|
||||||
|
|
||||||
|
typealias Relationships = NoRelationships
|
||||||
|
}
|
||||||
|
|
||||||
|
typealias TestEntity11 = BasicEntity<TestEntityType11>
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -597,3 +597,92 @@ let ten_different_type_includes = """
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
""".data(using: .utf8)!
|
""".data(using: .utf8)!
|
||||||
|
|
||||||
|
let eleven_different_type_includes = """
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"type": "test_entity1",
|
||||||
|
"id": "2DF03B69-4B0A-467F-B52E-B0C9E44FCECF",
|
||||||
|
"attributes": {
|
||||||
|
"foo": "Hello",
|
||||||
|
"bar": 123
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "test_entity2",
|
||||||
|
"id": "90F03B69-4DF1-467F-B52E-B0C9E44FC333",
|
||||||
|
"attributes": {
|
||||||
|
"foo": "World",
|
||||||
|
"bar": 456
|
||||||
|
},
|
||||||
|
"relationships": {
|
||||||
|
"entity1": {
|
||||||
|
"data": {
|
||||||
|
"type": "test_entity1",
|
||||||
|
"id": "2DF03B69-4B0A-467F-B52E-B0C9E44FCECF"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "test_entity3",
|
||||||
|
"id": "11223B69-4DF1-467F-B52E-B0C9E44FC443",
|
||||||
|
"relationships": {
|
||||||
|
"entity1": {
|
||||||
|
"data": {
|
||||||
|
"type": "test_entity1",
|
||||||
|
"id": "2DF03B69-4B0A-467F-B52E-B0C9E44FCECF"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"entity2": {
|
||||||
|
"data": [
|
||||||
|
{
|
||||||
|
"type": "test_entity2",
|
||||||
|
"id": "90F03B69-4DF1-467F-B52E-B0C9E44FC333"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "test_entity6",
|
||||||
|
"id": "11113B69-4DF1-467F-B52E-B0C9E44FC444",
|
||||||
|
"relationships": {
|
||||||
|
"entity4": {
|
||||||
|
"data": {
|
||||||
|
"type": "test_entity4",
|
||||||
|
"id": "364B3B69-4DF1-467F-B52E-B0C9E44F666E"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "test_entity5",
|
||||||
|
"id": "A24B3B69-4DF1-467F-B52E-B0C9E44F436A"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "test_entity4",
|
||||||
|
"id": "364B3B69-4DF1-467F-B52E-B0C9E44F666E"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "test_entity7",
|
||||||
|
"id": "364B3B69-4DF1-222F-B52E-B0C9E44F666E"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "test_entity8",
|
||||||
|
"id": "364B3B69-4DF1-222F-B52E-B0C9E44F266F"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "test_entity9",
|
||||||
|
"id": "364B3B69-4DF1-218F-B52E-B0C9E44F2661"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "test_entity10",
|
||||||
|
"id": "264B3B69-4DF1-212F-B52E-B0C9E44F2660"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "test_entity11",
|
||||||
|
"id": "264B3B69-4DF3-212F-B32E-A0C9E44F26C0B"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
""".data(using: .utf8)!
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"type": "test_entity1",
|
|
||||||
"id": "2DF03B69-4B0A-467F-B52E-B0C9E44FCECF",
|
|
||||||
"attributes": {
|
|
||||||
"foo": "Hello",
|
|
||||||
"bar": 123
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"type": "test_entity1",
|
|
||||||
"id": "2DF03B69-4B0A-467F-B52E-B0C9E44FCECF",
|
|
||||||
"attributes": {
|
|
||||||
"foo": "Hello",
|
|
||||||
"bar": 123
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "test_entity2",
|
|
||||||
"id": "90F03B69-4DF1-467F-B52E-B0C9E44FC333",
|
|
||||||
"attributes": {
|
|
||||||
"foo": "World",
|
|
||||||
"bar": 456
|
|
||||||
},
|
|
||||||
"relationships": {
|
|
||||||
"entity1": {
|
|
||||||
"data": {
|
|
||||||
"type": "test_entity1",
|
|
||||||
"id": "2DF03B69-4B0A-467F-B52E-B0C9E44FCECF"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "test_entity4",
|
|
||||||
"id": "364B3B69-4DF1-467F-B52E-B0C9E44F666E"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"type": "test_entity1",
|
|
||||||
"id": "2DF03B69-4B0A-467F-B52E-B0C9E44FCECF",
|
|
||||||
"attributes": {
|
|
||||||
"foo": "Hello",
|
|
||||||
"bar": 123
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "test_entity2",
|
|
||||||
"id": "90F03B69-4DF1-467F-B52E-B0C9E44FC333",
|
|
||||||
"attributes": {
|
|
||||||
"foo": "World",
|
|
||||||
"bar": 456
|
|
||||||
},
|
|
||||||
"relationships": {
|
|
||||||
"entity1": {
|
|
||||||
"data": {
|
|
||||||
"type": "test_entity1",
|
|
||||||
"id": "2DF03B69-4B0A-467F-B52E-B0C9E44FCECF"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
[
|
|
||||||
{
|
|
||||||
"type": "test_entity1",
|
|
||||||
"id": "2DF03B69-4B0A-467F-B52E-B0C9E44FCECF",
|
|
||||||
"attributes": {
|
|
||||||
"foo": "Hello",
|
|
||||||
"bar": 123
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"type": "test_entity1",
|
|
||||||
"id": "90F03B69-4DF1-467F-B52E-B0C9E44FC333",
|
|
||||||
"attributes": {
|
|
||||||
"foo": "World",
|
|
||||||
"bar": 456
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
@@ -114,3 +114,10 @@ let poly_entity10 = """
|
|||||||
"id": "A24B3444-4DF1-467F-B52E-B0C9E12F436A"
|
"id": "A24B3444-4DF1-467F-B52E-B0C9E12F436A"
|
||||||
}
|
}
|
||||||
""".data(using: .utf8)!
|
""".data(using: .utf8)!
|
||||||
|
|
||||||
|
let poly_entity11 = """
|
||||||
|
{
|
||||||
|
"type": "test_entity11",
|
||||||
|
"id": "A24B3444-4DF1-467F-B52E-B0C9E12F4440"
|
||||||
|
}
|
||||||
|
""".data(using: .utf8)!
|
||||||
|
|||||||
Reference in New Issue
Block a user