{"action":"closed","issue":{"url":"https://api.github.com/repos/vapor/vapor/issues/671","repository_url":"https://api.github.com/repos/vapor/vapor","labels_url":"https://api.github.com/repos/vapor/vapor/issues/671/labels{/name}","comments_url":"https://api.github.com/repos/vapor/vapor/issues/671/comments","events_url":"https://api.github.com/repos/vapor/vapor/issues/671/events","html_url":"https://github.com/vapor/vapor/issues/671","id":185886665,"number":671,"title":"Serialization","user":{"login":"joanromano","id":1227808,"avatar_url":"https://avatars.githubusercontent.com/u/1227808?v=3","gravatar_id":"","url":"https://api.github.com/users/joanromano","html_url":"https://github.com/joanromano","followers_url":"https://api.github.com/users/joanromano/followers","following_url":"https://api.github.com/users/joanromano/following{/other_user}","gists_url":"https://api.github.com/users/joanromano/gists{/gist_id}","starred_url":"https://api.github.com/users/joanromano/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/joanromano/subscriptions","organizations_url":"https://api.github.com/users/joanromano/orgs","repos_url":"https://api.github.com/users/joanromano/repos","events_url":"https://api.github.com/users/joanromano/events{/privacy}","received_events_url":"https://api.github.com/users/joanromano/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":3,"created_at":"2016-10-28T10:09:58Z","updated_at":"2016-11-02T11:46:27Z","closed_at":"2016-11-02T11:46:27Z","body":"# Serialization\n- Author(s): [Alex Manzella](https://github.com/MP0w), [Joan Romano](https://github.com/joanromano)\n## Introduction\n\nCustom serialization of objects is required by Vapor in order to return full JSON Response objects (https://vapor.github.io/documentation/guide/json.html). \n\nWe would like to use a built-in serialization mechanism that will allow Vapor users to use any custom struct/class to define models that just get serialized.\n## Motivation\n\nWe checked the documentation to see how Vapor handle Objects to JSON serialization and looks like everyone is responsible to create is own.\n\nWe are working on something very similar to Vapor (the APIs are \"surprisingly\" almost equal) but with a different purpose -> https://github.com/devlucky/Kakapo (dynamically mock network requests).\nKakapo has a quite powerful serialization (IMO 😁) and we were wondering if we should exact it into an own lib since can be useful as standalone package.\n\nThe library is well tested and stable, and we really think this might be useful for your framework.\n## Proposed solution\n\nKakapo supports simple Obj->JSON serialization by mirroring the object and recursively serialize it:\n\n```\nclass Parrot: Serializable {\n   let name: String\n   let friends: [Parrot]\n}\n```\n\nYou can also customize the serialization using `CustomSerializable`. As a proof of concept, based on this protocol, we created a JSON API (http://jsponapi.org) serializer that just works.\n\n```\nstruct User: JSONAPIEntity {\n   let id: String\n   let userName: String\n   let friends: [Parrot] // this will end up in relationships if parrot is `JSONAPIEntity`\n}\n```\n\nAnd much more like `SerializationTransformers`:\n\n```\nSnakeCaseTransformer(User(id: \"2\", userName: \"Kakapo\", friends: [])) -> during serialization userName becomes user_name\n```\n\nSo the idea is to bring together Vapor's `ResponseRepresentable` and Kakapo's `Serializable` in order to be able to use the former when having to return objects in the routing closure.\n## Code snippets\n\nIn order to make it compatible, we first need to make `Serializable` conform to `ResponseRepresentable` on Kakapo. \n\n```\nextension Serializable: ResponseRepresentable {\n    func makeResponse() throws -> Response {\n        // Construct Response here out of Serializable object\n    }\n}\n```\n\nAfter that, using it should be easy. Given the class:\n\n```\nclass User: Serializable {\n   let name: String\n   let surname: String\n}\n```\n\nWe would return it from any given droplet:\n\n```\ndrop.get(\"hello\") {\n   (request) in\n   let user = User(name: \"foo\", surname: \"bar\") // might come from db or whatever\n   return user\n}\n```\n## Impact\n\nNo impact on existing code. New code will just benefit from this.\n## Alternatives considered\n\nNo alternatives were considered.\n"}}
{"actor":{"display_login":"LoganWright"}}