Skip to content

Commit

Permalink
Add first routing extension, fix some links stuff
Browse files Browse the repository at this point in the history
  • Loading branch information
Koray Koska committed May 10, 2017
1 parent da550db commit 6f4fdfa
Show file tree
Hide file tree
Showing 10 changed files with 103 additions and 24 deletions.
2 changes: 1 addition & 1 deletion Sources/VaporJsonApi/Config/JsonApiConfig.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public struct JsonApiConfig {
}

// ******* Pagination specific *******
public static var defaultPaginator: JsonApiPaginator = JsonApiPagedPaginator()
// public static var defaultPaginator: JsonApiPaginator.Type = JsonApiPagedPaginator()
public static var defaultPageSize: Int = 10
public static var maximumPageSize: Int = 20
}
10 changes: 9 additions & 1 deletion Sources/VaporJsonApi/Config/JsonApiPaginator.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,17 @@
//

public protocol JsonApiPaginator {

var pageCount: Int { get }
var pageOffset: Int { get }
}

public class JsonApiPagedPaginator: JsonApiPaginator {

public var pageCount: Int
public var pageOffset: Int

public init(pageCount: Int, pageSize: Int) {
self.pageCount = pageCount
self.pageOffset = (pageSize * pageCount) - pageCount
}
}
2 changes: 1 addition & 1 deletion Sources/VaporJsonApi/Json/JsonApiResourceObject.swift
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ public class JsonApiRelationshipsObject: JSONRepresentable {
var json = try JSON(node: [:])

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

return json
Expand Down
2 changes: 1 addition & 1 deletion Sources/VaporJsonApi/Resources/JsonApiChildrenModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Fluent

public struct JsonApiChildrenModel {

public typealias JsonApiChildrenGetter = () throws -> [JsonApiResourceModel]
public typealias JsonApiChildrenGetter = (_ paginator: JsonApiPaginator) throws -> [JsonApiResourceModel]
public typealias JsonApiChildrenAdder = ([JsonApiResourceModel]) throws -> ()
public typealias JsonApiChildrenReplacer = ([JsonApiResourceModel]) throws -> ()

Expand Down
30 changes: 20 additions & 10 deletions Sources/VaporJsonApi/Resources/JsonApiResourceController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ public protocol JsonApiResourceController {

public extension JsonApiResourceController {

public var resourceType: JsonApiResourceType {
return Resource.resourceType
}

/**
* The `getResources` method is responsible for get requests to the resource collection.
*
Expand Down Expand Up @@ -110,28 +114,26 @@ public extension JsonApiResourceController {
return JsonApiResponse(status: .ok, document: document)
}
} else if let childrenCollection = try resource.childrenRelationships()[relationshipType] {
let children = try childrenCollection.getter()

let page = try pageForQuery(query: query)
let pageNumber = page.pageNumber
let pageCount = page.pageCount

// TODO: Pagination
// let resources = try children.limit(pageCount, withOffset: (pageNumber * pageCount) - pageCount).all()
let resources = children
let paginator = JsonApiPagedPaginator(pageCount: pageCount, pageSize: pageNumber)
let resources = try childrenCollection.getter(paginator)

let jsonDocument = try document(forResources: resources, baseUrl: req.uri)

return JsonApiResponse(status: .ok, document: jsonDocument)
} else if let siblingsCollection = try resource.siblingsRelationships()[relationshipType] {
let siblings = try siblingsCollection.getter()

let page = try pageForQuery(query: query)
let pageNumber = page.pageNumber
let pageCount = page.pageCount

// TODO: Pagination
// let resources = try siblings.limit(pageCount, withOffset: (pageNumber * pageCount) - pageCount).all()
let resources = siblings
let paginator = JsonApiPagedPaginator(pageCount: pageCount, pageSize: pageNumber)
let resources = try siblingsCollection.getter(paginator)

let jsonDocument = try document(forResources: resources, baseUrl: req.uri)

return JsonApiResponse(status: .ok, document: jsonDocument)
Expand All @@ -157,16 +159,24 @@ public extension JsonApiResourceController {
throw JsonApiUnsupportedMediaTypeError(mediaType: req.contentTypeHeaderValue() ?? "*No Content-Type header*")
}

guard let type = req.json?["type"]?.string else {
guard let type = req.jsonApiJson?["type"]?.string else {
throw JsonApiParameterMissingError(parameter: "type")
}
guard type == Resource.resourceType.parse() else {
throw JsonApiTypeConflictError(type: type)
}

let node = req.json?["data"]?["attributes"]?.makeNode()
let bodyData = req.jsonApiJson?["data"]

let node = bodyData?["attributes"]?.makeNode()
var resource = try Resource(node: node)

// TODO: Set relationships
if let relationships = bodyData?["relationships"]?.object {
for r in relationships {

}
}
try resource.save()

// Return newly saved object as jsonapi resource
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -143,18 +143,18 @@ public extension JsonApiResourceRepresentable {
public func makeChildrenRelationshipObject (
name: String,
type: JsonApiResourceModel.Type,
getter: (() throws -> [JsonApiResourceModel])? = nil,
getter: ((_ paginator: JsonApiPaginator) throws -> [JsonApiResourceModel])? = nil,
baseUrl: URI,
resourcePath: String,
meta: JsonApiMeta? = nil,
data: Bool = false
) throws -> JsonApiRelationshipObject {
let links = self.relationshipLinks(name: name, baseUrl: baseUrl, resourcePath: resourcePath)

// TODO: Pagination
var resourceLinkage: JsonApiResourceLinkage? = nil
if data {
if let children = try getter?() {
// TODO: Dynamic page size and count
if let children = try getter?(JsonApiPagedPaginator(pageCount: 1, pageSize: 50)) {
var resourceIdentifierObjects = [JsonApiResourceIdentifierObject]()
for c in children {
guard let id = c.id?.string ?? c.id?.int?.string else {
Expand All @@ -173,18 +173,18 @@ public extension JsonApiResourceRepresentable {
public func makeSiblingsRelationshipObject (
name: String,
type: JsonApiResourceModel.Type,
getter: (() throws -> [JsonApiResourceModel])? = nil,
getter: ((_ paginator: JsonApiPaginator) throws -> [JsonApiResourceModel])? = nil,
baseUrl: URI,
resourcePath: String,
meta: JsonApiMeta? = nil,
data: Bool = false
) throws -> JsonApiRelationshipObject {
let links = self.relationshipLinks(name: name, baseUrl: baseUrl, resourcePath: resourcePath)

// TODO: Pagination
var resourceLinkage: JsonApiResourceLinkage? = nil
if data {
if let siblings = try getter?() {
// TODO: Dynamic page size and count
if let siblings = try getter?(JsonApiPagedPaginator(pageCount: 1, pageSize: 50)) {
var resourceIdentifierObjects = [JsonApiResourceIdentifierObject]()
for s in siblings {
guard let id = s.id?.string ?? s.id?.int?.string else {
Expand Down
6 changes: 3 additions & 3 deletions Sources/VaporJsonApi/Resources/JsonApiSiblingsModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Fluent

public struct JsonApiSiblingsModel {

public typealias JsonApiSiblingsGetter = () throws -> [JsonApiResourceModel]
public typealias JsonApiSiblingsGetter = (_ paginator: JsonApiPaginator) throws -> [JsonApiResourceModel]
public typealias JsonApiSiblingsAdder = ([JsonApiResourceModel]) throws -> ()
public typealias JsonApiSiblingsReplacer = ([JsonApiResourceModel]) throws -> ()

Expand All @@ -29,8 +29,8 @@ public struct JsonApiSiblingsModel {
}

public init<S: JsonApiResourceModel, T: JsonApiResourceModel>(model: S, siblingType: T.Type, localKey: String? = nil, foreignKey: String? = nil) {
getter = {
let elements: [S] = try model.siblings(localKey, foreignKey).all()
getter = { paginator in
let elements: [S] = try model.siblings(localKey, foreignKey).limit(paginator.pageCount, withOffset: paginator.pageOffset).all()
return elements
}

Expand Down
24 changes: 24 additions & 0 deletions Sources/VaporJsonApi/Toolbox/Droplet+VaporJsonApi.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
//
// Droplet+VaporJsonApi.swift
// VaporJsonApi
//
// Created by Koray Koska on 10/05/2017.
//
//

import Vapor
import HTTP

public extension Droplet {

public func jsonApiResource<C: JsonApiResourceController>(controller: C) {
let resourceType = controller.resourceType.parse()
// Get routes
get(resourceType, handler: controller.getResources)
get(resourceType, String.self, handler: controller.getResource)
get(resourceType, String.self, String.self, handler: controller.getRelatedResource)

// Post routes
post(resourceType, handler: controller.postResource)
}
}
37 changes: 37 additions & 0 deletions Sources/VaporJsonApi/Toolbox/Message+VaporJsonApi.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
//
// Message+VaporJsonApi.swift
// VaporJsonApi
//
// Created by Koray Koska on 10/05/2017.
//
//

import Vapor
import HTTP

public extension Message {

public var jsonApiJson: JSON? {
get {
if let existing = storage["jsonApiJson"] as? JSON {
return existing
} else if fulfillsJsonApiContentTypeResponsibilities() {
guard case let .data(body) = body else { return nil }
guard let jsonApiJson = try? JSON(bytes: body) else { return nil }
storage["jsonApiJson"] = jsonApiJson
return jsonApiJson
} else {
return nil
}
}
set(jsonApiJson) {
if let data = jsonApiJson {
if let body = try? Body(data) {
self.body = body
headers[HeaderKey.contentType] = JsonApiConfig.mediaTypeValue
}
}
storage["jsonApiJson"] = json
}
}
}
2 changes: 1 addition & 1 deletion Sources/VaporJsonApi/Toolbox/RequestExtensions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import Vapor
import HTTP

extension Request {
extension Message {

// TODO: The media type checking should be done as described in the RFC Guide for media types but for now
// this is enough...
Expand Down

0 comments on commit 6f4fdfa

Please sign in to comment.