{"id":37019015,"url":"https://github.com/devslm/jsonapi-simple","last_synced_at":"2026-01-14T02:02:32.585Z","repository":{"id":57734769,"uuid":"213713788","full_name":"devslm/jsonapi-simple","owner":"devslm","description":"Simple implementation of the JSON:API specification (only required output fields)","archived":false,"fork":false,"pushed_at":"2023-08-02T11:12:58.000Z","size":158,"stargazers_count":2,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2023-08-02T12:39:07.080Z","etag":null,"topics":["api","java","jsonapi","library"],"latest_commit_sha":null,"homepage":"","language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/devslm.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","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":"2019-10-08T17:56:09.000Z","updated_at":"2022-12-07T08:14:32.000Z","dependencies_parsed_at":"2023-01-26T03:46:18.217Z","dependency_job_id":null,"html_url":"https://github.com/devslm/jsonapi-simple","commit_stats":null,"previous_names":["seregaslm/jsonapi-simple"],"tags_count":11,"template":null,"template_full_name":null,"purl":"pkg:github/devslm/jsonapi-simple","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devslm%2Fjsonapi-simple","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devslm%2Fjsonapi-simple/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devslm%2Fjsonapi-simple/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devslm%2Fjsonapi-simple/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/devslm","download_url":"https://codeload.github.com/devslm/jsonapi-simple/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/devslm%2Fjsonapi-simple/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28408711,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T01:52:23.358Z","status":"online","status_checked_at":"2026-01-14T02:00:06.678Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"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":["api","java","jsonapi","library"],"created_at":"2026-01-14T02:02:31.948Z","updated_at":"2026-01-14T02:02:32.571Z","avatar_url":"https://github.com/devslm.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"## Overview\nSimple implementation of the [JSON:API](https://jsonapi.org) specification (only required output fields).\nThis library implements only top-level fields: **data**, **links**, **errors** and **meta** without any **relationships**, **includes**\nand others. \n\nOften we only need standard of output all our endpoints especially when using many types of communications like HTTP query,\nwebsockets, queues etc and don't need complex entities inner relationships in our API but it's good if implementing some\nexists standards so this library for this goals.\n\n## Docs\n[See project page](https://devslm.github.io/jsonapi-simple/)\n\n## Usage\nAdd dependency to your project:\n```xml\n\u003cdependency\u003e\n    \u003cgroupId\u003ecom.slm-dev\u003c/groupId\u003e\n    \u003cartifactId\u003ejsonapi-simple\u003c/artifactId\u003e\n    \u003cversion\u003e1.12.0\u003c/version\u003e\n\u003c/dependency\u003e\n```\n\n\u003e **Warning:**\n\u003e The id field is included in the attributes because it more convenient for API clients.\n\n### Navigation\n  - [Build Response](#build-response)\n  - [Filtering](#filtering)\n  - [Sparse fieldsets](#sparse-fieldsets)\n  - [Pagination](#pagination)\n  - [Sorting](#sorting)\n  - [Examples](#other-response-examples)\n\n### Build Response\n\nSee documentation part: [response structure](https://jsonapi.org/format/#document-structure)\n\nEach response DTO should contain the annotation ```@JsonApiType(\"resource-type\")``` with any resource type identifier and\nthe annotation ```@JsonApiId``` without arguments on field which will be unique identifier this item, usually this \nfield is ```id```.\n\nIf we want to use data types like lists, maps etc. in the response we can set manually data type to avoid exception \n(see example below). \n\nEach response may contain generics (if you planning to use OPENAPI) or may not (without OPENAPI), for example both \nvariants correct:\n```java\npublic class RestController {\n    // The simplest option without OPENAPI support\n    public Response responseWithoutGenerics() {\n        return Response.builder()\n           .build();\n    }\n  \n    // This option will display correctly in OPENAPI with all DTO fields \n    public Response\u003cSomeDto\u003e responseWithGenerics() {\n        return Response.\u003cSomeDto, SomeDto\u003ebuilder()\n           .build();\n    }\n}\n```\n\nParametrized response may be 2 types:\n  - as list - first parameter in response builder must be only ```\u003cList\u003cData\u003cYourDto\u003e\u003e\u003e```:\n    ```java\n    public class RestController {\n        public Response\u003cList\u003cData\u003cSomeDto\u003e\u003e\u003e responseAsList() {\n            return Response.\u003cList\u003cData\u003cSomeDto\u003e\u003e, SomeDto\u003ebuilder()\n               .build();\n        }\n    }\n    ```\n  - as object:\n    ```java\n    public class RestController {\n        public Response\u003cSomeDto\u003e responseAsObject() {\n            return Response.\u003cSomeDto, SomeDto\u003ebuilder()\n               .build();\n        }\n    }\n    ```\n  - as empty response with ```Void``` class as parameter:\n    ```java\n    public class RestController {\n        public Response\u003cVoid\u003e responseAsObject() {\n            return Response.\u003cVoid, Void\u003ebuilder()\n               .build();\n        }\n    }\n    ```\n\nData types other than the DTO class (lists, maps etc.) can't have required annotations, so we can set data type manually:\n```java\n@RestController\n@RequestMapping(value = \"/api/v1/app\", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)\npublic class RestController {\n    @GetMapping\n    public Response\u003cSomeDto\u003e responseAsObject() {\n        return Response.\u003cSomeDto, SomeDto\u003ebuilder()\n            .jsonApiId(\"some-id\")\n            .jsonApiType(\"some-data-type\")\n            .data(Map.of(\"name\", \"Test string\"))\n            .build();\n    }\n}\n```\nThis produces response like:\n```json\n{\n  \"data\": {\n    \"type\":\"some-data-type\",\n    \"id\":\"\u003crandom-uuid-id\u003e or \u003cfixed-id\u003e\",\n    \"attributes\": {\n      \"id\":\"\u003crandom-uuid-id\u003e or \u003cfixed-id\u003e\",\n      \"name\": \"Test string\"\n    },\n    \"links\": {\n      \"self\": \"/some-data-type/\u003crandom-uuid-id\u003e\"\n    }\n  },\n  \"meta\": {\n    \"api\": {\n      \"version\":\"1\"\n    },\n    \"page\": {\n      \"maxSize\":25,\n      \"total\":1\n    }\n  }\n}\n```\n#### Method **jsonApiType** must be called before method **data**! With invalid calls order exception will be thrown!\n#### When set manually data type random response id (UUID) will be generated! You can set manually by method **jsonApiId**\n\nYou can add **URI** prefix for self links, by default using prefix only from **@JsonApiType** annotation\nfor example:\n```java\n@RestController\n@RequestMapping(value = \"/api/v1/app\", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)\npublic class RestController {\n    @GetMapping\n    public Response\u003cSomeDto\u003e responseAsObject() {\n        return Response.\u003cSomeDto, SomeDto\u003ebuilder()\n            .uri(\"/api/v1/app\")\n            .build();\n    }\n}\n```\nThis produces self links like (data fields are omitted):\n```json\n{\n  \"data\": { \n    \"links\": {\n      \"self\": \"/api/v1/app/test-object/7a543e90-2961-480e-b1c4-51249bf0c566\"\n    }\n  },\n  \"meta\": {}\n}\n```\nWe can also use spring placeholders in the uri the same with the **@RequestMapping** value. In this case\nwe must add all placeholder values in the same order as in the uri. Supported placeholders format:\n  - {some_id}\n  - {someId}\n  - ${some_id}\n  - ${someId}\n\n```java\n@RestController\n@RequestMapping(value = \"/api/v1/books/{book_id}/users/${userId}\", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)\npublic class RestController {\n    @GetMapping\n    public Response\u003cSomeDto\u003e responseAsObject() {\n        final int bookId = 1024;\n        final int userId = 2048;\n \n        return Response.\u003cSomeDto, SomeDto\u003ebuilder()\n            .uri(\"/api/v1/books/{book_id}/users/${userId}\", bookId, userId)\n            .build();\n    }\n}\n```\nThis produces self links like (data fields are omitted):\n```json\n{\n  \"data\": { \n    \"links\": {\n      \"self\": \"/api/v1/books/1024/users/2048/test-object/7a543e90-2961-480e-b1c4-51249bf0c566\"\n    }\n  },\n  \"meta\": {}\n}\n```\n\n### Filtering\n\nSee documentation part: [fetching-filtering](https://jsonapi.org/format/#fetching-filtering)\n\nIf you want to use request filters with annotation ```@RequestJsonApiFilter``` add argument resolver in your configuration \nfor example:\n```java\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class ApplicationConfig implements WebMvcConfigurer {\n    @Override\n    public void addArgumentResolvers(List\u003cHandlerMethodArgumentResolver\u003e argumentResolvers) {\n        argumentResolvers.add(new JsonApiFilterArgumentResolver());\n    }\n}\n```\n\nThen you can use annotation ```@RequestJsonApiFilter``` in controllers with one of the filtering operators:\n  - in\n  - not_in\n  - eq\n  - ne\n  - gt\n  - gte\n  - lt\n  - lte\n  - contain\n  - not_contain\n\n**If filter operator omitted ```eq``` will be used by default!** \n\nYou can get typed params from filter using next methods:\n  - listOfStringValues(param)\n  - listOfIntegerValues(param)\n  - listOfUuidValues(param)\n  - stringValue(param)\n  - intValue(param)\n  - longValue(param)\n  - boolValue(param)\n  - uuidValue(param)\n\nFor example:\n```java\n@Slf4j\n@RestController\n@AllArgsConstructor\n@RequestMapping(value = \"/app\", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)\npublic class RestController {\n    @GetMapping\n    public Response\u003cVoid\u003e get(final @RequestJsonApiFilter Filter filter) throws Exception {\n        if (filter.hasParam(\"key\")) {\n            final List\u003cString\u003e filterValues = filter.listOfStringValues(\"key\");\n            final UUID filterUuidValue = filter.uuidValue(\"key\");\n\n            // do something with filter param\n        }\n        return Response.\u003cVoid, Void\u003ebuilder()\n           .build();\n    }\n}\n```\nNow if request will be contained fields like ```filter[key1][in]=value1,value2\u0026filter[key2]=value1``` we can get them in \nthe ```Filter``` object.\n\n### Sparse fieldsets\n\nSee documentation part: [fetching-sparse-fieldsets](https://jsonapi.org/format/#fetching-sparse-fieldsets)\n\nIf you want to use request sparse fieldsets with annotation ```@RequestJsonApiFieldSet``` add argument resolver in your \nconfiguration for example:\n```java\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class ApplicationConfig implements WebMvcConfigurer {\n    @Override\n    public void addArgumentResolvers(List\u003cHandlerMethodArgumentResolver\u003e argumentResolvers) {\n        argumentResolvers.add(new JsonApiSpreadFieldSetArgumentResolver());\n    }\n}\n```\n\nThen you can use annotation ```@RequestJsonApiFieldSet``` in controllers.\n\nFor example:\n```java\n@Slf4j\n@RestController\n@AllArgsConstructor\n@RequestMapping(value = \"/app\", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)\npublic class RestController {\n    @GetMapping\n    public Response\u003cVoid\u003e get(final @RequestJsonApiFieldSet FieldSet fieldSet) throws Exception {\n        if (fieldSet.hasResource(\"resource-type\")) {\n            final Set\u003cString\u003e resourceFields = fieldSet.getFieldsByResourceType(\"resource-type\");\n\n            // do something with resource fields\n        }\n\n        if (fieldSet.isEmpty()) {\n            // do something with empty resource fields\n            // there we can add for example any default fields\n            fieldSet.addFields(\"resource-type\", Set.of(\"default_field\"));\n        }\n\n        if (!fieldSet.containsFields(Set.of(\"required_field_1\", \"required_field_2\"))) {\n            // do something when required fields in resource fields\n            // are absent\n        }\n        return Response.\u003cVoid, Void\u003ebuilder()\n           .build();\n    }\n}\n```\nNow if request will be contained fields like ```fields[resource-type-1]=field_1,field_2\u0026fields[resource-type-2]=field_3```\nwe can get them in the ```FieldSet``` object.\n\n### Pagination\n\nSee documentation part: [fetching-pagination](https://jsonapi.org/format/#fetching-pagination)\n\nIf you want to use request page with annotation ```@RequestJsonApiPage``` add argument resolver in your configuration \nfor example:\n```java\nimport org.springframework.context.annotation.Configuration;\n\n@Configuration\npublic class ApplicationConfig implements WebMvcConfigurer {\n    @Override\n    public void addArgumentResolvers(List\u003cHandlerMethodArgumentResolver\u003e argumentResolvers) {\n        argumentResolvers.add(new JsonApiPageArgumentResolver());\n    }\n}\n```\n\nThen you can use annotation ```@RequestJsonApiPage``` in controllers and get standard spring Pageable object.\n\nFor example:\n```java\n@Slf4j\n@RestController\n@AllArgsConstructor\n@RequestMapping(value = \"/app\", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)\npublic class RestController {\n    @GetMapping\n    public Response\u003cVoid\u003e get(final @RequestJsonApiPage Pageable page) throws Exception {\n        return Response.\u003cVoid, Void\u003ebuilder()\n            .build();\n    }\n}\n```\n\nNow if request will be contained fields like ```page[number]=3\u0026page[size]=10``` we can get them in the ```Pageable``` object.\n\nSupported fields for the page number are:\n  - **page[number]**\n  - **page[page]**\n  \nAnd for the page size are:\n  - **page[size]**\n  - **page[limit]**\n\n#### Request page always starts from 0 for compatible with spring repositories and etc.!\n#### If request page number \u003c 1 resolver always return number = 0 and if size \u003c 1 it always returns default value = 25!\n\n### Sorting\n\nSee documentation part: [fetching-sorting](https://jsonapi.org/format/#fetching-sorting)\n\nIf you want to use request sort with annotation ```@RequestJsonApiPage``` add argument resolver in your configuration\nas described in section [Pagination](#pagination).\n\nThen you can use annotation ```@RequestJsonApiPage``` in controllers and get standard spring Pageable object.\n\nFor example:\n```java\n@Slf4j\n@RestController\n@AllArgsConstructor\n@RequestMapping(value = \"/app\", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)\npublic class RestController {\n    @GetMapping\n    public Response\u003cVoid\u003e get(final @RequestJsonApiPage Pageable page) throws Exception {\n        final Sort sort = page.getSort();\n        // do anything with sort\n        \n        return Response.\u003cVoid, Void\u003ebuilder()\n            .build();\n    }\n}\n```\n\nNow if request will be contained list of fields like ```sort=field1,field2,-field3``` we can get them in the ```Pageable``` object.\n\nFor ASC order we just put fields name as is, for example: ```sort=name,age,...``` (see JSON:API spec).\n\nFor DESC order we should put fields name with prefix **-**, for example: ```sort=-name,age,...``` (see JSON:API spec).\n\n### Other response examples\nExample response with one data object:\n```java\n// Pseudo code\n@JsonApiType(\"test-object\")\npublic static class TestDto {\n    @JsonApiId\n    private UUID id;\n    private String name;\n    private LocalDateTime createDate;\n}\n\npublic class Test {\n    public Response\u003cTestDto\u003e main() {\n        return Response.\u003cTestDto, TestDto\u003ebuilder()\n            .data(\n                TestDto.builder()\n                    .id(UUID.randomUUID())\n                    .name(\"Test string\")\n                    .createDate(LocalDateTime.now(ZoneOffset.UTC))\n                    .build()\n            ).build();\n    }\n}\n```\n```json\n{\n  \"data\": {\n    \"type\":\"test-object\",\n    \"id\":\"7a543e90-2961-480e-b1c4-51249bf0c566\",\n    \"attributes\": {\n      \"id\":\"7a543e90-2961-480e-b1c4-51249bf0c566\",\n      \"name\":\"Test string\",\n      \"createDate\":\"2019-10-08T18:46:53.40297\"\n    }, \n    \"links\": {\n      \"self\": \"/test-object/7a543e90-2961-480e-b1c4-51249bf0c566\"\n    }\n  },\n  \"meta\": {\n    \"api\": {\n      \"version\":\"1\"\n    },\n    \"page\": {\n      \"maxSize\":25,\n      \"total\":1\n    }\n  }\n}\n```\n\nExample response with list of data objects:\n```java\n// Pseudo code\n@JsonApiType(\"test-object\")\npublic static class TestDto {\n    @JsonApiId\n    private UUID id;\n    private String name;\n    private LocalDateTime createDate;\n}\n\npublic class Test {\n    public Response\u003cList\u003cData\u003cTestDto\u003e\u003e\u003e main() {\n        return Response.\u003cList\u003cData\u003cTestDto\u003e\u003e, TestDto\u003ebuilder()\n            .data(\n                Arrays.asList(\n                    TestDto.builder()\n                        .id(UUID.randomUUID())\n                        .name(\"Test string 1\")\n                        .createDate(LocalDateTime.now(ZoneOffset.UTC))\n                        .build(),\n                    TestDto.builder()\n                        .id(UUID.randomUUID())\n                        .name(\"Test string 2\")\n                        .createDate(LocalDateTime.now(ZoneOffset.UTC))\n                        .build()\n                )\n            ).build();\n    }\n}\n```\n```json\n{\n  \"data\": [ \n    {\n      \"type\":\"test-object\",\n      \"id\":\"7a543e90-2961-480e-b1c4-51249bf0c566\",\n      \"attributes\": {\n        \"id\":\"7a543e90-2961-480e-b1c4-51249bf0c566\",\n        \"name\":\"Test string 1\",\n        \"createDate\":\"2019-10-08T18:46:53\"\n      }, \n      \"links\": {\n        \"self\": \"/test-object/7a543e90-2961-480e-b1c4-51249bf0c566\"\n      }\n    },\n    {\n      \"type\":\"test-object\", \n      \"id\":\"b4070518-e9fc-11e9-81b4-2a2ae2dbcce4\",\n      \"attributes\": {\n        \"id\":\"b4070518-e9fc-11e9-81b4-2a2ae2dbcce4\",\n        \"name\":\"Test string 2\",\n        \"createDate\":\"2019-10-08T18:46:51\"\n      }, \n      \"links\": {\n        \"self\": \"/test-object/b4070518-e9fc-11e9-81b4-2a2ae2dbcce4\"\n      }\n    }\n  ],\n  \"meta\": {\n    \"api\": {\n      \"version\":\"1\"\n    },\n    \"page\": {\n      \"maxSize\":25,\n      \"total\":2\n    }\n  }\n}\n```\n\nExample response with error (data is empty, so we use ```Void``` class as generic parameter):\n```java\n// Pseudo code\npublic class Test {\n    public Response\u003cVoid\u003e main() {\n        return Response.\u003cVoid, Void\u003ebuilder()\n            .error(\n                HttpStatus.BAD_REQUEST,\n                \"20045\",\n                \"Some errors occurred!\"\n            ).build();\n    }\n}\n```\n```json\n{\n  \"errors\": [\n    {\n      \"status\": 400,\n      \"code\": \"20045\",\n      \"detail\": \"Some errors occurred!\"\n    }\n  ],\n  \"meta\": {\n    \"api\": {\n      \"version\": \"1\"\n    },\n    \"page\": {\n      \"maxSize\": 25,\n      \"total\": 0\n    }\n  }\n}\n```\n\nExample response with error with meta field (data is empty so we use ```Void```class as generic parameter):\n```java\n// Pseudo code\npublic class Test {\n    public Response\u003cVoid\u003e main() {\n        final ErrorMetaDto errorMeta = new ErrorMetaDto(\n            UUID.randomUUID(),\n            \"Test meta value\",\n            Set.of(\n                \"Value 1\",\n                \"Value 2\"\n            )\n        );\n        return Response.\u003cVoid, Void\u003ebuilder()\n            .error(\n                HttpStatus.BAD_REQUEST,\n                \"20045\",\n                \"Some errors occurred!\",\n                errorMeta\n            ).build();\n    }\n}\n```\n```json\n{\n    \"errors\": [\n        {\n            \"status\": 400,\n            \"code\": \"20045\",\n            \"detail\": \"Some errors occurred!\",\n            \"meta\": {\n                \"id\": \"7a543e90-2961-480e-b1c4-51249bf0c566\",\n                \"value\": \"Test meta value\",\n                \"codes\": [\n                    \"Value 1\",\n                    \"Value 2\"\n                ]\n            }\n        }\n    ],\n    \"meta\": {\n        \"api\": {\n            \"version\": \"1\"\n        },\n        \"page\": {\n            \"maxSize\": 25,\n            \"total\": 0\n        }\n    }\n}\n```\n\nExample response with error with links (data is empty, so we use ```Void``` class as generic parameter):\n```java\n// Pseudo code\npublic class Test {\n    public Response\u003cVoid\u003e main() {\n        final Error.ErrorLink errorLink = Error.ErrorLink\n            .builder()\n            .about(\"https://example.org/docs/TOKEN_ERROR\")\n            .build();\n        \n        return Response.\u003cVoid, Void\u003ebuilder()\n            .error(\n                HttpStatus.BAD_REQUEST,\n                \"20045\",\n                \"Some errors occurred!\",\n                errorLink\n            ).build();\n    }\n}\n```\n```json\n{\n  \"errors\": [\n    {\n      \"status\": 400,\n      \"code\": \"20045\",\n      \"detail\": \"Some errors occurred!\",\n      \"links\": {\n          \"about\": \"https://example.org/docs/20045\"\n      }\n    }\n  ],\n  \"meta\": {\n    \"api\": {\n      \"version\": \"1\"\n    },\n    \"page\": {\n      \"maxSize\": 25,\n      \"total\": 0\n    }\n  }\n}\n```\n\nExample response with validation error and field name with invalid data (data is empty so we use ```Void``` \nclass as generic parameter):\n```java\n// Pseudo code\npublic class Test {\n    public Response\u003cVoid\u003e main() {\n        return Response.\u003cVoid, Void\u003ebuilder()\n            .validationError(\"field-name\", \"Field must be greater 0!\")\n            .build();\n    }\n}\n```\n```json\n{\n  \"errors\": [\n    {\n      \"status\": 400,\n      \"code\": \"VALIDATION_ERROR\",\n      \"detail\": \"Field must be greater 0!\",\n      \"source\": {\n        \"parameter\": \"field-name\"\n      }\n    }\n  ],\n  \"meta\": {\n    \"api\": {\n      \"version\": \"1\"\n    },\n    \"page\": {\n      \"maxSize\": 25,\n      \"total\": 0\n    }\n  }\n}\n```\n\nExample response with trace id (trace id can be string or UUID):\n```java\n// Pseudo code\npublic class Test {\n    public Response\u003cVoid\u003e main() {\n        return Response.\u003cVoid, Void\u003ebuilder()\n            .data(\n                TestDto.builder()\n                    .id(UUID.randomUUID())\n                    .name(\"Test string\")\n                    .createDate(LocalDateTime.now(ZoneOffset.UTC))\n                    .build()\n            ).metaTrace(new Meta.Trace(UUID.randomUUID()))\n            .build();\n    }\n}\n```\n```json\n{\n    \"data\": {\n        \"type\":\"test-object\",\n        \"id\":\"7a543e90-2961-480e-b1c4-51249bf0c566\",\n        \"attributes\": {\n            \"id\":\"7a543e90-2961-480e-b1c4-51249bf0c566\",\n            \"name\":\"Test string\",\n            \"createDate\":\"2019-10-08T18:46:53.40297\"\n        },\n        \"links\": {\n            \"self\": \"/test-object/7a543e90-2961-480e-b1c4-51249bf0c566\"\n        }\n    },\n    \"meta\": {\n        \"api\": {\n            \"version\":\"1\"\n        },\n        \"page\": {\n            \"maxSize\":25,\n            \"total\":1\n        },\n        \"trace\": {\n            \"id\": \"1a443e90-6961-480e-b1c4-51249bf0c566\"\n        }\n    }\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevslm%2Fjsonapi-simple","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdevslm%2Fjsonapi-simple","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdevslm%2Fjsonapi-simple/lists"}