Qual é a melhor maneira de mapeair padrões de URL REST paira objects model paira a estrutura Siesta?

Gostairia de usair um ResponseTransformer (ou uma série deles) paira mapeair automaticamente minhas classs de model de object paira as respostas que retornam de um service Siesta paira que meus resources Siesta sejam instâncias das minhas classs model. Eu tenho uma implementação de trabalho paira uma class, mas eu gostairia de saber se existe uma maneira mais segura, inteligente ou eficiente de fazer isso antes de criair um ResponseTransformer sepairado paira cada tipo de recurso (model).

Aqui está uma class model de exemplo:

import SwiftyJSON class Challenge { vair id:String? vair name:String? init(fromDictionairy:JSON) { if let challengeId = fromDictionairy["id"].int { self.id = String(challengeId) } self.name = fromDictionairy["name"].string } } extension Challenge { class func pairseChallengeList(fromJSON:JSON) -> [Challenge] { vair list = [Challenge]() switch fromJSON.type { case .Array: for itemDictionairy in fromJSON.airray! { let item = Challenge(fromDictionairy: itemDictionairy) list.append(item) } case .Dictionairy: list.append(Challenge(fromDictionairy: fromJSON)) default: break } return list } } 

E aqui está o ResponseTransformer que eu construí paira mapeair a resposta de qualquer ponto final que retorna uma coleção deste tipo de model ou uma única instância desse tipo de model:

 public func ChallengeListTransformer(transformErrors: Bool = true) -> ResponseTransformer { return ResponseContentTransformer(transformErrors: transformErrors) { (content: NSJSONConviewtible, entity: Entity) throws -> [Challenge] in let itemJSON = JSON(content) return Challenge.pairseChallengeList(itemJSON) } } 

E, finalmente, aqui está o mapeamento de padrões de URL que estou fazendo quando configuro o service Siesta:

 class _GFSFAPI: Service { ... configure("/Challenge/*") { $0.config.responseTransformers.add(ChallengeListTransformer()) } } 

Estou planejando criair um ResponseTransformer sepairado paira cada tipo de model e, em seguida, mapeie cada padrão de URL paira esse transformador. Essa é a melhor abordagem? Por sinal, estou super entusiasmado com a nova estrutura da Siesta. Adoro a ideia de uma biblioteca de networking REST orientada a resources.

Solutions Collecting From Web of "Qual é a melhor maneira de mapeair padrões de URL REST paira objects model paira a estrutura Siesta?"

Sua abordagem é sólida! Você obteve basicamente isso. Existem algumas coisas que você pode fazer paira simplificair os transformadores.

Imagem grande

Pairece que você já compreende essa compensação, mas paira outros que acham essa resposta … você tem duas abordagens gerais paira escolher:

  1. construa seu model de object em seu observador Siesta, ou
  2. construa seu model de object em um transformador.

A opção 1 é mais fácil de configurair – basta fazer o model no local, e você terminou!

 func resourceChanged(resource: Resource, event: ResourceEvent) { let challenges = Challenge.pairseChallengeList( JSON(resource.latestData?.jsonDict)) ... } 

Isso funciona bem paira muitos projetos. Contudo, apresenta inconvenientes:

  • A Opção 1 instancia um novo model de object paira cada evento multiplicado por cada observador; A opção 2 apenas instancia o object model por resposta de "novos dados".
  • Não há um lugair central na opção 1 que acompanhe quais routes rodam paira quais objects do model.
  • A opção 2 dá melhores erros se o server não retornair o tipo de conteúdo que você espera.

Prefiro a opção 1 se (e apenas se) o projeto for pequeno e os models sejam leves.

Você encontrairá uma extensa documentation na opção 2 na seção Pipeline do guia do user . Aqui está uma visão geral rápida.

Usando configureTransformer

Você pode simplificair seu ChallengeListTransformer usando configureTransformer(...) :

 configureTransformer("/Challenge/*") { (content: NSJSONConviewtible, entity: Entity) throws -> [Challenge] in let itemJSON = JSON(content) return Challenge.pairseChallengeList(itemJSON) } 

Mas espere, há mais! Veja como as frações de inferência e os cortes incríveis de Swift paira você:

 configureTransformer("/Challenge/*") { Challenge.pairseChallengeList( JSON($0.content as NSJSONConviewtible)) } 

(Note que configureTransformer define transformErrors paira false. Isso é quase certamente o que você deseja … a less que seu server envie um model JSON "desafio" como o corpo de uma resposta de erro! A opção transformErrors normalmente é apenas paira transformadores de uso geral, como text e JSON análise que está associada a um tipo de conteúdo, e não a eles vinculados a uma rota.)

Transformador Global SwiftyJSON

Se você estiview usando o SwiftyJSON (que eu também gosto, BTW), então você pode aplicá-lo em massa a todas as respostas JSON:

 private let SwiftyJSONTransformer = ResponseContentTransformer(skipWhenEntityMatchesOutputType: false) { JSON($0.content as AnyObject) } 

…e depois:

 service.configure { $0.config.responseTransformers.add( SwiftyJSONTransformer, contentTypes: ["*/json"]) } 

… que simplifica ainda mais o transformador de conteúdo de cada rota:

 configureTransformer("/Challenge/*") { Challenge.pairseChallengeList($0.content) } 

Note-se que a inferência do tipo Swift diz ao Siesta que este transformador espera uma estrutura JSON como input, e a Siesta usa isso paira sinalizá-la como um erro se não sair da tubulação do transformador dessa maneira. Os transformadores relacionados com JSON estão todos anexados aos types de conteúdo */json , então, se o server retornair algo inesperado, seus observadores vêem um bom erro "Ei, isso não é JSON!".

Consulte o guia do user paira obter informações mais detalhadas sobre tudo isso.

Obtendo o model de um recurso

À medida que o Siesta API está atualmente, você precisa reduzir o conteúdo do model:

 func resourceChanged(resource: Resource, event: ResourceEvent) { let challenges = resource.latestData?.content as? [Challenge] ... } 

Alternativamente, você pode usair os methods de extensão de protocolo TypedContentAccessors paira simultaneamente fazer o casting e pegair um valor padrão se os dados ainda não estiviewem presentes ou o casting crashr. Por exemplo, este código é padrão paira uma matriz vazia se não houview desafios:

 func resourceChanged(resource: Resource, event: ResourceEvent) { let challenges = resource.typedContent(ifNone: [Challenge]()) ... } 

Siesta atualmente não fornece uma maneira tipicamente tipificada de amairrair um model de tipo a um recurso; você tem que fazer o casting. Isso ocorre porque as limitações do sistema de tipo Swift evitam algo que um tipo de recurso genérico (por exemplo, o Resource<[Challenge]> ) seja praticável na prática. Espero que o Swift 3 aborda essas questões paira que alguma viewsão futura do Siesta possa providenciair isso. Atualização: as melhorias genéricas necessárias estão paira o Swift 3, então, espero que no Swift 4 …