<code> { "$schema": "http://json-schema.org/draft-04/schema#", "type": "object", "properties": { "address": { "type": "object", "properties": { "streetAddress": { "type": "string" }, "city": { "type": "string" } }, "required": [ "streetAddress", "city" ] }, "phoneNumber": { "type": "array", "items": { "type": "object", "properties": { "location": { "type": "string" }, "code": { "type": "integer" } }, "required": [ "location", "code" ] } } }, "required": [ "address", "phoneNumber" ] } </code>
<code> import Foundation protocol IRestHelp { var details:String {get} var params :String {get} var schema :String {get} } </code>
<code> import PerfectLib class RestApi { var prefix:String? var commands:[String]? = nil var handler:RequestHandler? init(prefix:String?=nil, commands:[String]? = nil, handler:RequestHandler?=nil) { self.prefix = prefix self.commands = commands self.handler = handler } } </code>
<code> import Foundation import PerfectLib class RestApiReg { typealias APIList = [RestApi] // MARK: - Public Properties private var commandList = APIList() // MARK: - Private Properties private var globalRegistered = false // MARK: - Singletone Implementation private init() { } private class var sharedInstance: RestApiReg { struct Static { static var instance: RestApiReg? static var token: dispatch_once_t = 0 } dispatch_once(&Static.token) { Static.instance = RestApiReg() } return Static.instance! } // MARK: - Methods of class class func registration(list:APIList) { self.sharedInstance.commandList = list self.sharedInstance.linkAll() } class func add(command:RestApi) { self.sharedInstance.commandList += [command] self.sharedInstance.add(command) } class var list: APIList { return self.sharedInstance.commandList } // MARK: - Private methods private func linkAll() { Routing.Handler.registerGlobally() self.globalRegistered = true for api in self.commandList { self.add(api) } } private func add(api:RestApi) { if !self.globalRegistered { Routing.Handler.registerGlobally() } if let handler = api.handler { let prefix = api.prefix == nil ? "*" : api.prefix! if let commands = api.commands { Routing.Routes[prefix, commands] = { (_:WebResponse) in handler } } else { Routing.Routes[prefix] = { (_:WebResponse) in handler } } } } } </code>
<code> import Foundation import PerfectLib class HelpHandler:RequestHandler, IRestHelp { var details = "Show server comands list" var params = "" var schema = "" func handleRequest(request: WebRequest, response: WebResponse) { let list = self.createList() let html = ContentPage(title:"HELP", body:list).page(request.documentRoot) response.appendBodyString("\(html)") response.requestCompletedCallback() } private func createList() -> String { let list = RestApiReg.list var code = "" let allPrefixes = list.map { (api) -> String in api.prefix != nil ? api.prefix! : "/*" } let groups = Set<String>(allPrefixes).sort() for group in groups { let commandsApi = self.commandsByGroup(group, list:list) code += self.titleOfGroup(group) code += self.tableWithCommnads(commandsApi) } return code } private func commandsByGroup(group:String, list:RestApiReg.APIList) -> [String:RestApi] { var dict = [String:RestApi]() let commandsOfGroup = list.filter({ (api) -> Bool in api.prefix == group }) for api in commandsOfGroup { if let commands = api.commands { for cmd in commands { dict[cmd] = api } } else { dict[""] = api } } return dict } private func titleOfGroup(group:String) -> String { return " <B>\(group):</B> " } private func tableWithCommnads(commands:[String:RestApi]) -> String { let sortedList = commands.keys.sort() var table = "" table += "<table border = \"1px\" width=\"100%\">" for name in sortedList { let cmd = commands[name]! table += "<tr>" table += "<td width=\"15%\"><a href=\"\(name)\">\(name)</a></td>" if let help = cmd.handler as? IRestHelp { table += "<td>\(help.details)</td>" table += "<td>\(help.params)</td>" table += help.schema.characters.count > 0 ? "<td><a href=\"\(help.schema)\">/\(help.schema)</a></td>" : "<td></td>" } else { table += "<td></td>" table += "<td></td>" table += "<td></td>" } table += "</tr>" } table += "</table>" return table } } </code>
<code> import Foundation import PerfectLib class CarsJson:RequestHandler, IRestHelp { var details = "Show complexly JSON object" var params = "{}" var schema = "cars.json" func handleRequest(request: WebRequest, response: WebResponse) { let car1:[JSONKey: AnyObject] = ["Wheel":4, "Color":"Black"] let car2:[JSONKey: AnyObject] = ["Wheel":3, "Color":["mixColor":0xf2f2f2]] let cars = [car1, car2] let restResponse = RESTResponse(data:cars) response.appendBodyBytes(restResponse.array) response.requestCompletedCallback() } } </code>
<code> public func PerfectServerModuleInit() { RestApiReg.add(RestApi(handler: StaticFileHandler())) RestApiReg.add(RestApi(prefix: "GET", commands: ["/dynamic"], handler: StaticPageHandler(staticPage: "index.mustache"))) RestApiReg.add(RestApi(prefix: "GET", commands: ["/index", "/list"], handler: StaticPageHandler(staticPage: "index.html"))) RestApiReg.add(RestApi(prefix: "GET", commands: ["/hello"], handler: HelloHandler())) RestApiReg.add(RestApi(prefix: "GET", commands: ["/help"], handler: HelpHandler())) RestApiReg.add(RestApi(prefix: "GET", commands: ["/cars", "/car"], handler: CarsJson())) RestApiReg.add(RestApi(prefix: "POST", commands: ["/list"], handler: CarsJson())) } </code>
Source: https://habr.com/ru/post/283432/
All Articles