Skip to content

Commit

Permalink
Add JsonApiResourceModel and refactor some json classes
Browse files Browse the repository at this point in the history
  • Loading branch information
Koray Koska committed May 1, 2017
1 parent 8c13be3 commit 8e47395
Show file tree
Hide file tree
Showing 7 changed files with 130 additions and 51 deletions.
2 changes: 2 additions & 0 deletions Sources/VaporJsonApi/Config/JsonApiConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,6 @@ public struct JsonApiConfig {

// ******* Pagination specific *******
public static var defaultPaginator: JsonApiPaginator = JsonApiPagedPaginator()
public static var defaultPageSize: Int = 10
public static var maximumPageSize: Int = 20
}
43 changes: 33 additions & 10 deletions Sources/VaporJsonApi/Json/JsonApiResourceObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Vapor
public class JsonApiResourceObject: JSONRepresentable {

public let id: String
public let type: String
public let type: JsonApiResourceType
public let attributes: JsonApiAttributesObject?
public let relationships: JsonApiRelationshipsObject?
public let links: JsonApiLinksObject?
Expand All @@ -29,7 +29,7 @@ public class JsonApiResourceObject: JSONRepresentable {
*/
public init(
id: String,
type: String,
type: JsonApiResourceType,
attributes: JsonApiAttributesObject? = nil,
relationships: JsonApiRelationshipsObject? = nil,
links: JsonApiLinksObject? = nil,
Expand All @@ -45,7 +45,7 @@ public class JsonApiResourceObject: JSONRepresentable {
public func makeJSON() throws -> JSON {
var json = try JSON(node: [
"id": Node(id),
"type": Node(type)
"type": Node(type.parse())
])

if let attributes = attributes {
Expand Down Expand Up @@ -90,23 +90,46 @@ public class JsonApiAttributesObject: JSONRepresentable {

public class JsonApiRelationshipsObject: JSONRepresentable {

public let relationshipObjects: [JsonApiRelationshipObject]

public init(relationshipObjects: [JsonApiRelationshipObject]) {
self.relationshipObjects = relationshipObjects
}

public func makeJSON() throws -> JSON {
var json = try JSON(node: [:])

for relationshipObject in relationshipObjects {
json[relationshipObject.name] = try relationshipObjects.makeJSON()
}

return json
}
}

public class JsonApiRelationshipObject: JSONRepresentable {

public let name: String
public let links: JsonApiLinksObject?
public let data: JsonApiResourceLinkage?
public let meta: JsonApiMeta?

public init(links: JsonApiLinksObject, data: JsonApiResourceLinkage? = nil, meta: JsonApiMeta? = nil) {
public init(name: String, links: JsonApiLinksObject, data: JsonApiResourceLinkage? = nil, meta: JsonApiMeta? = nil) {
self.name = name
self.links = links
self.data = data
self.meta = meta
}

public init(data: JsonApiResourceLinkage, links: JsonApiLinksObject? = nil, meta: JsonApiMeta? = nil) {
public init(name: String, data: JsonApiResourceLinkage, links: JsonApiLinksObject? = nil, meta: JsonApiMeta? = nil) {
self.name = name
self.links = links
self.data = data
self.meta = meta
}

public init(meta: JsonApiMeta, links: JsonApiLinksObject? = nil, data: JsonApiResourceLinkage? = nil) {
public init(name: String, meta: JsonApiMeta, links: JsonApiLinksObject? = nil, data: JsonApiResourceLinkage? = nil) {
self.name = name
self.links = links
self.data = data
self.meta = meta
Expand All @@ -126,7 +149,7 @@ public class JsonApiRelationshipsObject: JSONRepresentable {
if let meta = meta {
json["meta"] = try meta.makeJSON()
}

return json
}
}
Expand Down Expand Up @@ -234,7 +257,7 @@ public class JsonApiResourceLinkage: JSONRepresentable {
public class JsonApiResourceIdentifierObject: JSONRepresentable {

public let id: String
public let type: String
public let type: JsonApiResourceType
public let meta: JsonApiMeta?

/**
Expand All @@ -244,7 +267,7 @@ public class JsonApiResourceIdentifierObject: JSONRepresentable {
* - parameter type: The `type` of this `ResourceIdentifierObject`.
* - parameter meta: An optional `meta` object to be added to the `ResourceIdentifierObject`.
*/
public init(id: String, type: String, meta: JsonApiMeta? = nil) {
public init(id: String, type: JsonApiResourceType, meta: JsonApiMeta? = nil) {
self.id = id
self.type = type
self.meta = meta
Expand All @@ -253,7 +276,7 @@ public class JsonApiResourceIdentifierObject: JSONRepresentable {
public func makeJSON() throws -> JSON {
var json = try JSON(node: [
"id": Node(id),
"type": Node(type)
"type": Node(type.parse())
])
if let meta = meta {
json["meta"] = try meta.makeJSON()
Expand Down
37 changes: 0 additions & 37 deletions Sources/VaporJsonApi/ResourceController.swift

This file was deleted.

47 changes: 47 additions & 0 deletions Sources/VaporJsonApi/Resources/JsonApiResourceController.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//
// JsonApiResourceController.swift
// VaporJsonApi
//
// Created by Koray Koska on 30/04/2017.
//
//

import Vapor
import HTTP

public protocol JsonApiResourceController {
associatedtype Resource: JsonApiResourceModel

func getResources(_ req: Request) throws -> ResponseRepresentable
}

public extension JsonApiResourceController {

/**
* The `getResources` method is responsible for get requests to the resource collection.
*
* Example: `/articles` for the article resource.
*
* - parameter req: The `Request` which fired this method.
*/
func getResources(_ req: Request) throws -> ResponseRepresentable {

guard req.fulfillsJsonApiAcceptResponsibilities() else {
throw JsonApiNotAcceptableError(mediaType: req.acceptHeaderValue() ?? "*No Accept header*")
}

let query = req.jsonApiQuery()

let pageCount = query["page"]?["size"]?.string?.int ?? JsonApiConfig.defaultPageSize
if pageCount > JsonApiConfig.maximumPageSize {
throw JsonApiInvalidPageValueError(page: "page[size]", value: query["page"]?["size"]?.string ?? "*Nothing*")
}
let pageNumber = query["page"]?["number"]?.string?.int ?? 1
if pageNumber < 1 {
throw JsonApiInvalidPageValueError(page: "page[number]", value: query["page"]?["number"]?.string ?? "*Nothing*")
}
let resources = try Resource.query().limit(pageCount, withOffset: (pageNumber * pageCount) - pageCount).all()

return "Hello"
}
}
39 changes: 39 additions & 0 deletions Sources/VaporJsonApi/Resources/JsonApiResourceModel.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
//
// JsonApiResourceModel.swift
// VaporJsonApi
//
// Created by Koray Koska on 01/05/2017.
//
//

import Vapor
import HTTP

public protocol JsonApiResourceModel: Model {

typealias JsonApiAttributes = [String: JSON?]
typealias JsonApiRelationships = [String: JsonApiResourceModel.Type]

var resourceType: JsonApiResourceType { get }

func attributes() throws -> JsonApiAttributes

func relationships() throws -> JsonApiRelationships
}

public extension JsonApiResourceModel {

public func makeResourceObject() throws -> JsonApiResourceObject {
guard let id = self.id?.string else {
throw JsonApiInternalServerError(title: "Internal Server Error", detail: "A fetched model does not seem to have a valid id.")
}
let attributes = JsonApiAttributesObject(attributes: try JSON(node: self.attributes()))
/*
let relationships = JsonApiRelationshipsObject(relationshipObjects: [])
let resourceObject = JsonApiResourceObject(id: id, type: resourceType, attributes: attributes, relationships: relationships, links: links, meta: meta)
*/

// TODO: Finish implementing makeResourceObject
throw JsonApiInternalServerError()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,11 @@
//
//

import Foundation

public protocol ResourceType {
public protocol JsonApiResourceType {
func parse() -> String
}

extension String: ResourceType {
extension String: JsonApiResourceType {

public func parse() -> String {
return self
Expand Down
7 changes: 7 additions & 0 deletions Sources/VaporJsonApi/Toolbox/RequestExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,10 @@ extension Request {
return accept.value
}
}

extension Request {

func jsonApiQuery() -> JSON {
return uri.jsonApiQuery()
}
}

0 comments on commit 8e47395

Please sign in to comment.