{"action":"created","comment":{"url":"https://api.github.com/repos/guardian/content-api-models/pulls/comments/79376552","id":79376552,"diff_hunk":"@@ -10,38 +10,8 @@ import com.gu.contentatom.thrift.atom.cta.CTAAtom\n import com.gu.contentapi.circe.CirceScroogeMacros._\n import com.gu.contentapi.client.model.v1._\n import org.joda.time.format.ISODateTimeFormat\n-import org.json4s.JValue\n \n-object CirceSerialization {\n-\n-  implicit val dateTimeDecoder = new Decoder[CapiDateTime] {\n-    final def apply(c: HCursor): Decoder.Result[CapiDateTime] = c.focus.asString match {\n-      case Some(value) =>\n-        val dateTime = ISODateTimeFormat.dateOptionalTimeParser().withOffsetParsed().parseDateTime(value)\n-        Xor.right(CapiDateTime.apply(dateTime.getMillis, dateTime.toString(ISODateTimeFormat.dateTime())))\n-      case _ => Xor.left(DecodingFailure(\"CapiDateTime\", c.history))\n-    }\n-  }\n-\n-  /**\n-    * Encoder to convert from a json4s JValue to a Circe Json\n-    */\n-  implicit val jvalueEncoder: Encoder[JValue] = new Encoder[JValue] {\n-    import org.json4s.JsonAST._\n-\n-    override def apply(j: JValue): Json = j match {\n-      case JBool(value) => Json.fromBoolean(value)\n-      case JString(value) => Json.fromString(value)\n-      case JInt(value) => Json.fromBigInt(value)\n-      case JLong(value) => Json.fromLong(value)\n-      case JDouble(value) => Json.fromDoubleOrNull(value)\n-      case JDecimal(value) => Json.fromBigDecimal(value)\n-      case JArray(elems) => Json.fromValues(elems.map(apply))\n-      case JObject(fields) => Json.fromFields(fields.map { case (key, value) => (key, apply(value)) })\n-      case JNull => Json.Null\n-      case JNothing => Json.Null\n-    }\n-  }\n+object CirceDecoders {","path":"json/src/main/scala/com/gu/contentapi/json/CirceDecoders.scala","position":36,"original_position":36,"commit_id":"a5aa195203744ab46b3672e5e6b12258a12a34aa","original_commit_id":"a5aa195203744ab46b3672e5e6b12258a12a34aa","user":{"login":"cb372","id":106760,"avatar_url":"https://avatars.githubusercontent.com/u/106760?v=3","gravatar_id":"","url":"https://api.github.com/users/cb372","html_url":"https://github.com/cb372","followers_url":"https://api.github.com/users/cb372/followers","following_url":"https://api.github.com/users/cb372/following{/other_user}","gists_url":"https://api.github.com/users/cb372/gists{/gist_id}","starred_url":"https://api.github.com/users/cb372/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/cb372/subscriptions","organizations_url":"https://api.github.com/users/cb372/orgs","repos_url":"https://api.github.com/users/cb372/repos","events_url":"https://api.github.com/users/cb372/events{/privacy}","received_events_url":"https://api.github.com/users/cb372/received_events","type":"User","site_admin":false},"body":"💯  for getting rid of the serialization/deserialization terminology","created_at":"2016-09-19T12:09:31Z","updated_at":"2016-09-19T12:09:31Z","html_url":"https://github.com/guardian/content-api-models/pull/60#discussion_r79376552","pull_request_url":"https://api.github.com/repos/guardian/content-api-models/pulls/60","_links":{"self":{"href":"https://api.github.com/repos/guardian/content-api-models/pulls/comments/79376552"},"html":{"href":"https://github.com/guardian/content-api-models/pull/60#discussion_r79376552"},"pull_request":{"href":"https://api.github.com/repos/guardian/content-api-models/pulls/60"}}},"pull_request":{"url":"https://api.github.com/repos/guardian/content-api-models/pulls/60","id":84831210,"html_url":"https://github.com/guardian/content-api-models/pull/60","diff_url":"https://github.com/guardian/content-api-models/pull/60.diff","patch_url":"https://github.com/guardian/content-api-models/pull/60.patch","issue_url":"https://api.github.com/repos/guardian/content-api-models/issues/60","number":60,"state":"open","locked":false,"title":"Thrift to circe encoders","user":{"login":"tomrf1","id":1513454,"avatar_url":"https://avatars.githubusercontent.com/u/1513454?v=3","gravatar_id":"","url":"https://api.github.com/users/tomrf1","html_url":"https://github.com/tomrf1","followers_url":"https://api.github.com/users/tomrf1/followers","following_url":"https://api.github.com/users/tomrf1/following{/other_user}","gists_url":"https://api.github.com/users/tomrf1/gists{/gist_id}","starred_url":"https://api.github.com/users/tomrf1/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/tomrf1/subscriptions","organizations_url":"https://api.github.com/users/tomrf1/orgs","repos_url":"https://api.github.com/users/tomrf1/repos","events_url":"https://api.github.com/users/tomrf1/events{/privacy}","received_events_url":"https://api.github.com/users/tomrf1/received_events","type":"User","site_admin":false},"body":"### Background\r\nWe've been migrating our json handling from json4s to circe.\r\nWe already have decoders, which turn circe json objects into circe. Concierge is using these.\r\nThis change adds encoders for going the other way.\r\n\r\n### Why do we need encoders?\r\n1. For building json responses in concierge, which some clients still need. At the moment, if a client requests format=json then concierge has to use json4s to do the conversion. We'd like to get rid of json4s from concierge as well.\r\n2. It's nice for testing.\r\n3. It would be nice to make the thrift encoder/decoder macros open source. There's a bit more to be done first.\r\n\r\n### Notes\r\n1. We were previously storing CapiDateTime with milliseconds, but dropping the milliseconds during deserialization. Now the encoder returns the datetime with milliseconds - this makes the code and the tests simpler.\r\n2. I've replaced SerializationSpec.scala with CirceRoundTripSpec.scala. As well as switching from json4s to circe, there's a slightly philosophical shift because the test files no longer contain the json that concierge produces (e.g. no bools as strings). The tests in this library validate the circe encoders/decoders, and concierge should (and does) test any crazy stringifying/destringifying that it does before or after building the thrift.\r\n3. I've removed all references to serialization/deserialization (which is what we called it with json4s) because I always get the terminology mixed up now that we have encoder/decoder as well.\r\n4. I removed Chris's excellent benchmarking module because we no longer need the comparison.\r\n\r\nThe associated concierge change is on its way...","created_at":"2016-09-12T08:19:09Z","updated_at":"2016-09-19T12:42:03Z","closed_at":null,"merged_at":null,"merge_commit_sha":"61e70f0b7b6bde03356c2c4a39d5f25e302a64af","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/guardian/content-api-models/pulls/60/commits","review_comments_url":"https://api.github.com/repos/guardian/content-api-models/pulls/60/comments","review_comment_url":"https://api.github.com/repos/guardian/content-api-models/pulls/comments{/number}","comments_url":"https://api.github.com/repos/guardian/content-api-models/issues/60/comments","statuses_url":"https://api.github.com/repos/guardian/content-api-models/statuses/a5aa195203744ab46b3672e5e6b12258a12a34aa","head":{"label":"guardian:thrift-to-circe-encoders","ref":"thrift-to-circe-encoders","sha":"a5aa195203744ab46b3672e5e6b12258a12a34aa","user":{"login":"guardian","id":164318,"avatar_url":"https://avatars.githubusercontent.com/u/164318?v=3","gravatar_id":"","url":"https://api.github.com/users/guardian","html_url":"https://github.com/guardian","followers_url":"https://api.github.com/users/guardian/followers","following_url":"https://api.github.com/users/guardian/following{/other_user}","gists_url":"https://api.github.com/users/guardian/gists{/gist_id}","starred_url":"https://api.github.com/users/guardian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/guardian/subscriptions","organizations_url":"https://api.github.com/users/guardian/orgs","repos_url":"https://api.github.com/users/guardian/repos","events_url":"https://api.github.com/users/guardian/events{/privacy}","received_events_url":"https://api.github.com/users/guardian/received_events","type":"Organization","site_admin":false},"repo":{"id":55155875,"name":"content-api-models","full_name":"guardian/content-api-models","owner":{"login":"guardian","id":164318,"avatar_url":"https://avatars.githubusercontent.com/u/164318?v=3","gravatar_id":"","url":"https://api.github.com/users/guardian","html_url":"https://github.com/guardian","followers_url":"https://api.github.com/users/guardian/followers","following_url":"https://api.github.com/users/guardian/following{/other_user}","gists_url":"https://api.github.com/users/guardian/gists{/gist_id}","starred_url":"https://api.github.com/users/guardian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/guardian/subscriptions","organizations_url":"https://api.github.com/users/guardian/orgs","repos_url":"https://api.github.com/users/guardian/repos","events_url":"https://api.github.com/users/guardian/events{/privacy}","received_events_url":"https://api.github.com/users/guardian/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/guardian/content-api-models","description":"Content-api thrift models","fork":false,"url":"https://api.github.com/repos/guardian/content-api-models","forks_url":"https://api.github.com/repos/guardian/content-api-models/forks","keys_url":"https://api.github.com/repos/guardian/content-api-models/keys{/key_id}","collaborators_url":"https://api.github.com/repos/guardian/content-api-models/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/guardian/content-api-models/teams","hooks_url":"https://api.github.com/repos/guardian/content-api-models/hooks","issue_events_url":"https://api.github.com/repos/guardian/content-api-models/issues/events{/number}","events_url":"https://api.github.com/repos/guardian/content-api-models/events","assignees_url":"https://api.github.com/repos/guardian/content-api-models/assignees{/user}","branches_url":"https://api.github.com/repos/guardian/content-api-models/branches{/branch}","tags_url":"https://api.github.com/repos/guardian/content-api-models/tags","blobs_url":"https://api.github.com/repos/guardian/content-api-models/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/guardian/content-api-models/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/guardian/content-api-models/git/refs{/sha}","trees_url":"https://api.github.com/repos/guardian/content-api-models/git/trees{/sha}","statuses_url":"https://api.github.com/repos/guardian/content-api-models/statuses/{sha}","languages_url":"https://api.github.com/repos/guardian/content-api-models/languages","stargazers_url":"https://api.github.com/repos/guardian/content-api-models/stargazers","contributors_url":"https://api.github.com/repos/guardian/content-api-models/contributors","subscribers_url":"https://api.github.com/repos/guardian/content-api-models/subscribers","subscription_url":"https://api.github.com/repos/guardian/content-api-models/subscription","commits_url":"https://api.github.com/repos/guardian/content-api-models/commits{/sha}","git_commits_url":"https://api.github.com/repos/guardian/content-api-models/git/commits{/sha}","comments_url":"https://api.github.com/repos/guardian/content-api-models/comments{/number}","issue_comment_url":"https://api.github.com/repos/guardian/content-api-models/issues/comments{/number}","contents_url":"https://api.github.com/repos/guardian/content-api-models/contents/{+path}","compare_url":"https://api.github.com/repos/guardian/content-api-models/compare/{base}...{head}","merges_url":"https://api.github.com/repos/guardian/content-api-models/merges","archive_url":"https://api.github.com/repos/guardian/content-api-models/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/guardian/content-api-models/downloads","issues_url":"https://api.github.com/repos/guardian/content-api-models/issues{/number}","pulls_url":"https://api.github.com/repos/guardian/content-api-models/pulls{/number}","milestones_url":"https://api.github.com/repos/guardian/content-api-models/milestones{/number}","notifications_url":"https://api.github.com/repos/guardian/content-api-models/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/guardian/content-api-models/labels{/name}","releases_url":"https://api.github.com/repos/guardian/content-api-models/releases{/id}","deployments_url":"https://api.github.com/repos/guardian/content-api-models/deployments","created_at":"2016-03-31T14:12:52Z","updated_at":"2016-08-15T11:39:52Z","pushed_at":"2016-09-19T10:52:54Z","git_url":"git://github.com/guardian/content-api-models.git","ssh_url":"git@github.com:guardian/content-api-models.git","clone_url":"https://github.com/guardian/content-api-models.git","svn_url":"https://github.com/guardian/content-api-models","homepage":"","size":2690,"stargazers_count":1,"watchers_count":1,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":2,"forks":2,"open_issues":2,"watchers":1,"default_branch":"master"}},"base":{"label":"guardian:master","ref":"master","sha":"086f57279106b68bab9a558cacb6763f42f5196f","user":{"login":"guardian","id":164318,"avatar_url":"https://avatars.githubusercontent.com/u/164318?v=3","gravatar_id":"","url":"https://api.github.com/users/guardian","html_url":"https://github.com/guardian","followers_url":"https://api.github.com/users/guardian/followers","following_url":"https://api.github.com/users/guardian/following{/other_user}","gists_url":"https://api.github.com/users/guardian/gists{/gist_id}","starred_url":"https://api.github.com/users/guardian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/guardian/subscriptions","organizations_url":"https://api.github.com/users/guardian/orgs","repos_url":"https://api.github.com/users/guardian/repos","events_url":"https://api.github.com/users/guardian/events{/privacy}","received_events_url":"https://api.github.com/users/guardian/received_events","type":"Organization","site_admin":false},"repo":{"id":55155875,"name":"content-api-models","full_name":"guardian/content-api-models","owner":{"login":"guardian","id":164318,"avatar_url":"https://avatars.githubusercontent.com/u/164318?v=3","gravatar_id":"","url":"https://api.github.com/users/guardian","html_url":"https://github.com/guardian","followers_url":"https://api.github.com/users/guardian/followers","following_url":"https://api.github.com/users/guardian/following{/other_user}","gists_url":"https://api.github.com/users/guardian/gists{/gist_id}","starred_url":"https://api.github.com/users/guardian/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/guardian/subscriptions","organizations_url":"https://api.github.com/users/guardian/orgs","repos_url":"https://api.github.com/users/guardian/repos","events_url":"https://api.github.com/users/guardian/events{/privacy}","received_events_url":"https://api.github.com/users/guardian/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/guardian/content-api-models","description":"Content-api thrift models","fork":false,"url":"https://api.github.com/repos/guardian/content-api-models","forks_url":"https://api.github.com/repos/guardian/content-api-models/forks","keys_url":"https://api.github.com/repos/guardian/content-api-models/keys{/key_id}","collaborators_url":"https://api.github.com/repos/guardian/content-api-models/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/guardian/content-api-models/teams","hooks_url":"https://api.github.com/repos/guardian/content-api-models/hooks","issue_events_url":"https://api.github.com/repos/guardian/content-api-models/issues/events{/number}","events_url":"https://api.github.com/repos/guardian/content-api-models/events","assignees_url":"https://api.github.com/repos/guardian/content-api-models/assignees{/user}","branches_url":"https://api.github.com/repos/guardian/content-api-models/branches{/branch}","tags_url":"https://api.github.com/repos/guardian/content-api-models/tags","blobs_url":"https://api.github.com/repos/guardian/content-api-models/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/guardian/content-api-models/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/guardian/content-api-models/git/refs{/sha}","trees_url":"https://api.github.com/repos/guardian/content-api-models/git/trees{/sha}","statuses_url":"https://api.github.com/repos/guardian/content-api-models/statuses/{sha}","languages_url":"https://api.github.com/repos/guardian/content-api-models/languages","stargazers_url":"https://api.github.com/repos/guardian/content-api-models/stargazers","contributors_url":"https://api.github.com/repos/guardian/content-api-models/contributors","subscribers_url":"https://api.github.com/repos/guardian/content-api-models/subscribers","subscription_url":"https://api.github.com/repos/guardian/content-api-models/subscription","commits_url":"https://api.github.com/repos/guardian/content-api-models/commits{/sha}","git_commits_url":"https://api.github.com/repos/guardian/content-api-models/git/commits{/sha}","comments_url":"https://api.github.com/repos/guardian/content-api-models/comments{/number}","issue_comment_url":"https://api.github.com/repos/guardian/content-api-models/issues/comments{/number}","contents_url":"https://api.github.com/repos/guardian/content-api-models/contents/{+path}","compare_url":"https://api.github.com/repos/guardian/content-api-models/compare/{base}...{head}","merges_url":"https://api.github.com/repos/guardian/content-api-models/merges","archive_url":"https://api.github.com/repos/guardian/content-api-models/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/guardian/content-api-models/downloads","issues_url":"https://api.github.com/repos/guardian/content-api-models/issues{/number}","pulls_url":"https://api.github.com/repos/guardian/content-api-models/pulls{/number}","milestones_url":"https://api.github.com/repos/guardian/content-api-models/milestones{/number}","notifications_url":"https://api.github.com/repos/guardian/content-api-models/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/guardian/content-api-models/labels{/name}","releases_url":"https://api.github.com/repos/guardian/content-api-models/releases{/id}","deployments_url":"https://api.github.com/repos/guardian/content-api-models/deployments","created_at":"2016-03-31T14:12:52Z","updated_at":"2016-08-15T11:39:52Z","pushed_at":"2016-09-19T10:52:54Z","git_url":"git://github.com/guardian/content-api-models.git","ssh_url":"git@github.com:guardian/content-api-models.git","clone_url":"https://github.com/guardian/content-api-models.git","svn_url":"https://github.com/guardian/content-api-models","homepage":"","size":2690,"stargazers_count":1,"watchers_count":1,"language":"Scala","has_issues":true,"has_downloads":true,"has_wiki":false,"has_pages":false,"forks_count":2,"mirror_url":null,"open_issues_count":2,"forks":2,"open_issues":2,"watchers":1,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/guardian/content-api-models/pulls/60"},"html":{"href":"https://github.com/guardian/content-api-models/pull/60"},"issue":{"href":"https://api.github.com/repos/guardian/content-api-models/issues/60"},"comments":{"href":"https://api.github.com/repos/guardian/content-api-models/issues/60/comments"},"review_comments":{"href":"https://api.github.com/repos/guardian/content-api-models/pulls/60/comments"},"review_comment":{"href":"https://api.github.com/repos/guardian/content-api-models/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/guardian/content-api-models/pulls/60/commits"},"statuses":{"href":"https://api.github.com/repos/guardian/content-api-models/statuses/a5aa195203744ab46b3672e5e6b12258a12a34aa"}}}}
{"actor":{"display_login":"cb372"}}