Skip to content

Commit 21d698c

Browse files
authored
Merge pull request #89 from mattpolzin/improve-links-documentation
better links documentation paired with a test to ensure documentation accuracy.
2 parents c645c73 + 92406d3 commit 21d698c

2 files changed

Lines changed: 141 additions & 0 deletions

File tree

Tests/JSONAPITests/ResourceObject/ResourceObjectTests.swift

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -623,6 +623,24 @@ extension ResourceObjectTests {
623623
test_DecodeEncodeEquality(type: TestEntity4WithMetaAndLinks.self,
624624
data: entity_some_relationships_some_attributes_with_meta_and_links)
625625
}
626+
627+
func test_fullLinksExample() {
628+
let entity = decoded(
629+
type: ResourceObjectLinksTest.Article.self,
630+
data: ResourceObjectLinksTest.json.data(using: .utf8)!
631+
)
632+
633+
XCTAssertEqual(entity.links.`self`.url.absoluteString, "http://example.com/articles/1")
634+
XCTAssertEqual(entity.relationships.author.links.`self`.url.absoluteString, "http://example.com/articles/1/relationships/author")
635+
XCTAssertEqual(entity.relationships.author.links.related.url.absoluteString, "http://example.com/articles/1/author")
636+
}
637+
638+
func test_fullLinksExample_encode() {
639+
test_DecodeEncodeEquality(
640+
type: ResourceObjectLinksTest.Article.self,
641+
data: ResourceObjectLinksTest.json.data(using: .utf8)!
642+
)
643+
}
626644
}
627645

628646
// MARK: With a Meta Attribute
@@ -963,3 +981,61 @@ extension ResourceObjectTests {
963981
let link1: Link<String, NoMetadata>
964982
}
965983
}
984+
985+
extension Foundation.URL : JSONAPIURL {}
986+
987+
enum ResourceObjectLinksTest {
988+
struct PersonStubDescription: JSONAPI.ResourceObjectDescription {
989+
static let jsonType: String = "people"
990+
991+
typealias Attributes = NoAttributes
992+
typealias Relationships = NoRelationships
993+
}
994+
995+
typealias Person = JSONAPI.ResourceObject<PersonStubDescription, NoMetadata, NoLinks, String>
996+
997+
struct ArticleAuthorRelationshipLinks: JSONAPI.Links {
998+
let `self`: JSONAPI.Link<URL, NoMetadata>
999+
let related: JSONAPI.Link<URL, NoMetadata>
1000+
}
1001+
1002+
struct ArticleLinks: JSONAPI.Links {
1003+
let `self`: JSONAPI.Link<URL, NoMetadata>
1004+
}
1005+
1006+
struct ArticleDescription: JSONAPI.ResourceObjectDescription {
1007+
static let jsonType: String = "articles"
1008+
1009+
struct Attributes: JSONAPI.Attributes {
1010+
let title: Attribute<String>
1011+
}
1012+
1013+
struct Relationships: JSONAPI.Relationships {
1014+
let author: ToOneRelationship<Person, NoIdMetadata, NoMetadata, ArticleAuthorRelationshipLinks>
1015+
}
1016+
}
1017+
1018+
typealias Article = JSONAPI.ResourceObject<ArticleDescription, NoMetadata, ArticleLinks, String>
1019+
1020+
static let json = """
1021+
{
1022+
"type": "articles",
1023+
"id": "1",
1024+
"attributes": {
1025+
"title": "Rails is Omakase"
1026+
},
1027+
"relationships": {
1028+
"author": {
1029+
"links": {
1030+
"self": "http://example.com/articles/1/relationships/author",
1031+
"related": "http://example.com/articles/1/author"
1032+
},
1033+
"data": { "type": "people", "id": "9" }
1034+
}
1035+
},
1036+
"links": {
1037+
"self": "http://example.com/articles/1"
1038+
}
1039+
}
1040+
"""
1041+
}

documentation/usage.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -509,6 +509,71 @@ A `Links` struct must contain only `Link` properties. Each `Link` property can e
509509

510510
You can specify `NoLinks` if the part of the document being described should not contain any `Links`.
511511

512+
**IMPORTANT:** The URL type used in links is a type conforming to `JSONAPIURL`. Any type that is both `Codable` and `Equatable` is eligible, but it must be conformed explicitly.
513+
514+
For example,
515+
```swift
516+
extension Foundation.URL: JSONAPIURL {}
517+
extension String: JSONAPIURL {}
518+
```
519+
520+
Here's an example of an "article" resource with some links object and some JSON it would be capable of parsing:
521+
```swift
522+
struct PersonStubDescription: JSONAPI.ResourceObjectDescription {
523+
// this is just a pretend model to be used in a relationship below.
524+
static let jsonType: String = "people"
525+
526+
typealias Attributes = NoAttributes
527+
typealias Relationships = NoRelationships
528+
}
529+
530+
typealias Person = JSONAPI.ResourceObject<PersonStubDescription, NoMetadata, NoLinks, String>
531+
532+
struct ArticleAuthorRelationshipLinks: JSONAPI.Links {
533+
let `self`: JSONAPI.Link<URL, NoMetadata>
534+
let related: JSONAPI.Link<URL, NoMetadata>
535+
}
536+
537+
struct ArticleLinks: JSONAPI.Links {
538+
let `self`: JSONAPI.Link<URL, NoMetadata>
539+
}
540+
541+
struct ArticleDescription: JSONAPI.ResourceObjectDescription {
542+
static let jsonType: String = "articles"
543+
544+
struct Attributes: JSONAPI.Attributes {
545+
let title: Attribute<String>
546+
}
547+
548+
struct Relationships: JSONAPI.Relationships {
549+
let author: ToOneRelationship<Person, NoIdMetadata, NoMetadata, ArticleAuthorRelationshipLinks>
550+
}
551+
}
552+
553+
typealias Article = JSONAPI.ResourceObject<ArticleDescription, NoMetadata, ArticleLinks, String>
554+
```
555+
```json
556+
{
557+
"type": "articles",
558+
"id": "1",
559+
"attributes": {
560+
"title": "Rails is Omakase"
561+
},
562+
"relationships": {
563+
"author": {
564+
"links": {
565+
"self": "http://example.com/articles/1/relationships/author",
566+
"related": "http://example.com/articles/1/author"
567+
},
568+
"data": { "type": "people", "id": "9" }
569+
}
570+
},
571+
"links": {
572+
"self": "http://example.com/articles/1"
573+
}
574+
}
575+
```
576+
512577
### `JSONAPI.RawIdType`
513578

514579
If you want to create new `JSONAPI.ResourceObject` values and assign them Ids then you will need to conform at least one type to `CreatableRawIdType`. Doing so is easy; here are two example conformances for `UUID` and `String` (via `UUID`):

0 commit comments

Comments
 (0)