{"id":17991401,"url":"https://github.com/jareware/json-dto","last_synced_at":"2025-06-25T23:04:19.977Z","repository":{"id":140155879,"uuid":"2152853","full_name":"jareware/JSON-DTO","owner":"jareware","description":"A simple JSON-DTO-binding module for the Play! Framework","archived":false,"fork":false,"pushed_at":"2011-08-09T11:39:27.000Z","size":112,"stargazers_count":5,"open_issues_count":2,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-06-25T23:04:09.419Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jareware.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2011-08-04T05:38:15.000Z","updated_at":"2017-04-26T01:25:23.000Z","dependencies_parsed_at":"2023-03-13T10:44:20.827Z","dependency_job_id":null,"html_url":"https://github.com/jareware/JSON-DTO","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/jareware/JSON-DTO","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jareware%2FJSON-DTO","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jareware%2FJSON-DTO/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jareware%2FJSON-DTO/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jareware%2FJSON-DTO/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jareware","download_url":"https://codeload.github.com/jareware/JSON-DTO/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jareware%2FJSON-DTO/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":261967126,"owners_count":23237662,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-10-29T19:21:55.787Z","updated_at":"2025-06-25T23:04:19.945Z","avatar_url":"https://github.com/jareware.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"JSON-DTO Module for Play!\n=========================\n\nSimple plugin and associated conventions for making JSON-DTO binding a breeze with the Play! Framework.\n\nInstallation\n------------\n\nThe easiest way to install is to [obtain a copy](https://github.com/jareware/JSON-DTO/zipball/master)\nof the JSON-DTO module and drop it under the `modules/` path of your Play! application.\n\nThe above method is deprecated, however, in favor of the new [dependency management system](http://www.playframework.org/documentation/latest/dependency).\nTo install the JSON-DTO module as a local module,\nextract a copy of the module to `/path/to/jsondto` and use something like the following in your `dependencies.yml`:\n\n\trequire:\n\t    - play\n\t    - jsondto -\u003e jsondto\n\n\trepositories:\n\n\t    - jsondto:\n\t        type: local\n\t        artifact: \"/path/to/jsondto\"\n\t        contains:\n\t            - jsondto -\u003e jsondto\n\nYou should be good to go.\n\nHow it works\n------------\n\nWhen building a RESTful JSON API with Play! (or with any web framework for that matter), you are often doing two things:\n\n1. Reading in requests that (may) contain a JSON representation of a model object\n1. Responding to requests with another (possible) such representation\n\nPlay! offers [automatic HTTP-POJO-binding](http://www.playframework.org/documentation/latest/controllers#pojo)\nwhich is great when reading in regular form data, but\nwhen building an API you often want to be very specific about what to expose.\nYou may want to change the public names of fields, or may want to add generated, read-only fields to your\nobjects.  One example of such a field could be a `url` field, which (for our purposes at least) is immutable, and must be generated whenever the\nobject is rendered out as JSON.\nThe default POJO-binding also only works with named request parameters, whereas one would like\nto read in the object from the request body, just as you respond with the object in the response body.\nFinally, as the Play! model objects are backed by a JPA Entity Manager and are thus part of a complex graph of objects,\nrendering a representation of the object relationships may get very hairy pretty quick.\n\nThe JSON-DTO module offers to solve these issues by using a [Data Transfer Object](http://en.wikipedia.org/wiki/Data_transfer_object)\nfor defining the JSON representation of a model object.  This takes away a lot of the magic involved with\nannotating your models for which fields to expose, which to allow editing for etc.  Instead, each model object that\ncan be represented as JSON (`JSONDTORepresentable`) explicitly defines that representation (`JSONDTO`)\nand methods for converting to and from such an instance.\n\nPlease find some concrete examples below.\n\nExamples\n--------\n\nLet's say we're building an API for maintaining a list of notes.  Our model object looks like:\n\n\t@Entity\n\tpublic class Note extends Model {\n\n\t\tpublic String title = \"\";\n\n\t\t@ManyToMany\n\t\tpublic List\u003cTag\u003e tags = new ArrayList\u003cTag\u003e();\n\n\t}\n\nWe want to give the Note's JSON representation the aforementioned immutable `url` field,\nand also render out the tags list as just a list of the names of the tags,\nnot the complete objects.  Here we go:\n\n\t@Entity\n\tpublic class Note extends Model implements JSONDTORepresentable\u003cNote.DTO\u003e {\n\n\t\tpublic String title = \"\";\n\n\t\t@ManyToMany\n\t\tpublic List\u003cTag\u003e tags = new ArrayList\u003cTag\u003e();\n\n\t\tpublic class DTO implements JSONDTO {\n\t\t\tpublic String my_title;\n\t\t\tpublic List\u003cString\u003e tags;\n\t\t\tpublic String url;\n\t\t}\n\n\t\t@Override\n\t\tpublic void merge(DTO dto) {\n\t\t\t// TODO\n\t\t}\n\n\t\t@Override\n\t\tpublic DTO toDTO() {\n\t\t\t// TODO\n\t\t}\n\n\t}\n\nBy implementing `JSONDTORepresentable` the model object signals that it can represent itself as a DTO if need be.\nWe define that representation to be `Note.DTO`,\nwhich is just a [POJO](http://en.wikipedia.org/wiki/Plain_Old_Java_Object) without any inheritance or annotations magic.\nIt contains the fields we want to expose within the JSON representation of the Note model.\nWe implement it as an inline class to keep these closely related classes together,\nthough you can just as well define the implementation of `JSONDTO` as a completely separate class.\n\nNote that the DTO differs from the actual model object - only the DTO has the `url` field,\nwhile the implicit `id` field of the model object is not exposed via the DTO.\nThe `title` field has also been renamed as `my_title`,\nsince that is how we want to expose it in our API.\n\nThe `JSONDTORepresentable` interface defines two methods, namely `merge(DTO)` and `toDTO()`.\nThe former should copy any properties from the DTO to the model object,\nwhile the latter should do the opposite, that is, produce an instance of `DTO` based on the properties of the model object.\nLet's look at an implementation of `toDTO()` first:\n\n\t@Override\n\tpublic DTO toDTO() {\n\n\t\tDTO dto = new DTO();\n\t\tdto.my_title = this.title;\n\t\tdto.url = Router.reverse(/* ... */).url;\n\t\tdto.tags = new ArrayList\u003cString\u003e();\n\n\t\tfor (Tag tag : this.tags)\n\t\t\tdto.tags.add(tag.name);\n\n\t\treturn dto;\n\n\t}\n\nTo do the opposite, we implement a `merge(DTO)` as well:\n\n\t@Override\n\tpublic void merge(DTO dto) {\n\n\t\tthis.title = dto.my_title;\n\n\t\tfor (String tagName : dto.tags) {\n\t\t\tTag tag = Tag.find(\"byName\", tagName).first();\n\t\t\tthis.tags.add(tag);\n\t\t}\n\n\t}\n\nNote that the `url` field is simply ignored since we want it to be read-only.\n\nTo make use of the model object and its DTO in a controller matching to a route `GET /notes/{id} Notes.getNote`,\nyou could do something like:\n\n\tpublic static void getNote(Long id) throws Exception {\n\n\t\tNote note = Note.findById(id);\n\n\t\tnotFoundIfNull(note);\n\n\t\tJSONDTOUtil.renderDTO(note, response);\n\n\t}\n\nThe response will have `Content-Type: application/json; charset=utf-8` and a body containing:\n\n\t{\"my_title\":\"Something\",\"tags\":[\"foo\",\"bar\"],\"url\":\"/notes/123\"}\n\nNote that we can pass the model object directly to `JSONDTOUtil.renderDTO()`,\nwhich will know to call `toDTO()` appropriately.\nYou can also pass in a list of model objects (that implement `JSONDTORepresentable`):\n\n\tpublic static void getAllNotes() throws Exception {\n\n\t\tList\u003cNote\u003e notes = Note.findAll();\n\n\t\tJSONDTOUtil.renderDTO(notes, response);\n\n\t}\n\nTo update a note, one could bind the following method to a route `PUT /notes/{id} Notes.updateNote`:\n\n\tpublic static void updateNote(Long id, Note.DTO noteDTO) {\n\n\t\tNote note = Note.findById(id);\n\n\t\tnotFoundIfNull(note);\n\n\t\tnote.merge(noteDTO);\n\t\tnote.save();\n\n\t}\n\nTo update the note, `PUT` to this controller method with `Content-Type: \"application/json\"` and a request body of:\n\n\t{\"my_title\":\"Something else\",\"tags\":[\"foobar\"]}\n\nNote that we have omitted the `url` field here, but it could just as well have been provided.\nIn fact, you can add any additional fields to the body,\nand they won't have an effect on `merge(DTO)` unless you explicitly specify within that method.\n\nFinally, to create a new note, for example with route `POST /notes` and the same request body as above:\n\n\tpublic static void createNote(Note.DTO noteDTO) {\n\n\t\tNote note = new Note();\n\t\tnote.merge(noteDTO);\n\t\tnote.save();\n\n\t}\n\nRunning the tests\n-----------------\n\nThe JSON-DTO module ships with unit and functional tests.\nTo run them, make sure the module is loaded and start Play! with the `test` framework ID.\nThe tests `JSONDTOFunctionalTest` and `JSONDTOUnitTest` will appear in the standard test runner UI at http://localhost:9000/@tests.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjareware%2Fjson-dto","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjareware%2Fjson-dto","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjareware%2Fjson-dto/lists"}