{"id":13620233,"url":"https://github.com/timacdonald/json-api","last_synced_at":"2026-01-06T00:19:39.664Z","repository":{"id":39742075,"uuid":"394276725","full_name":"timacdonald/json-api","owner":"timacdonald","description":"A lightweight API resource for Laravel that helps you adhere to the JSON:API standard. Supports sparse fieldsets, compound documents, and more.","archived":false,"fork":false,"pushed_at":"2025-03-30T22:56:57.000Z","size":1568,"stargazers_count":603,"open_issues_count":9,"forks_count":45,"subscribers_count":9,"default_branch":"main","last_synced_at":"2025-05-09T10:30:34.913Z","etag":null,"topics":["json-api","laravel","php"],"latest_commit_sha":null,"homepage":"","language":"PHP","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/timacdonald.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-08-09T12:08:42.000Z","updated_at":"2025-04-12T04:15:59.000Z","dependencies_parsed_at":"2024-05-12T23:31:50.770Z","dependency_job_id":"c3fed4ee-8da4-44dc-ae24-2efc6ab136dd","html_url":"https://github.com/timacdonald/json-api","commit_stats":{"total_commits":583,"total_committers":8,"mean_commits":72.875,"dds":"0.015437392795883409","last_synced_commit":"5c7f28bdc46ba078e2d8bfda307130095931a9a5"},"previous_names":[],"tags_count":18,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timacdonald%2Fjson-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timacdonald%2Fjson-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timacdonald%2Fjson-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/timacdonald%2Fjson-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/timacdonald","download_url":"https://codeload.github.com/timacdonald/json-api/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254081836,"owners_count":22011687,"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":["json-api","laravel","php"],"created_at":"2024-08-01T21:00:53.663Z","updated_at":"2026-01-06T00:19:39.658Z","avatar_url":"https://github.com/timacdonald.png","language":"PHP","funding_links":[],"categories":["PHP"],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/timacdonald/json-api/main/art/header.png\" alt=\"JSON:API Resource: a Laravel package by Tim MacDonald\"\u003e\u003c/p\u003e\n\n# `JSON:API` Resource for Laravel\n\nA lightweight API resource for Laravel that helps you adhere to the `JSON:API` standard with support for sparse fieldsets, compound documents, and more baked in.\n\n\u003e **Note** These docs are not designed to introduce you to the `JSON:API` specification and the associated concepts, instead you should [head over and read the specification](https://jsonapi.org) if you are not yet familiar with it. The documentation that follows only covers _how_ to implement the specification via the package.\n\n**Table of contents**\n- [Installation](#installation)\n- [Getting started](#getting-started)\n    - [Creating your first `JSON:API` resource](#creating-your-first-jsonapi-resource)\n    - [Adding attributes](#adding-attributes)\n    - [Adding relationships](#adding-relationships)\n- [A note on eager loading](#a-note-on-eager-loading)\n- [Digging deeper](#digging-deeper)\n    - [Attributes](#attributes)\n        - [`toAttributes()`](#toAttributes)\n        - [Sparse fieldsets](#sparse-fieldsets)\n        - [Minimal attributes](#minimal-attributes)\n        - [Lazy attribute evaluation](#lazy-attribute-evaluation)\n    - [Relationships](#relationships)\n        - [`toRelationships()`](#toRelationships)\n        - [Customising the relationship resource class guessing](#customising-the-relationship-resource-class-guessing)\n\n## Installation\n\nYou can install using [composer](https://getcomposer.org/) from [Packagist](https://packagist.org/packages/timacdonald/json-api).\n\n```sh\ncomposer require timacdonald/json-api\n```\n\n## Getting started\n\nThe `JsonApiResource` class provided by this package is a specialisation of Laravel's [Eloquent API resource](https://laravel.com/docs/eloquent-resources). All public facing APIs are still accessible; in a controller, for example, you interact with a `JsonApiResource` as you would with Laravel's `JsonResource` class.\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nuse App\\Http\\Resources\\UserResource;\nuse App\\Models\\User;\n\nclass UserController\n{\n    public function index()\n    {\n        $users = User::with([/* ... */])-\u003epaginate();\n\n        return UserResource::collection($users);\n    }\n\n    public function show(User $user)\n    {\n        $user-\u003eload([/* ... */]);\n\n        return UserResource::make($user);\n    }\n}\n```\n\nAs we make our way through the examples you will see that new APIs are introduced when interacting with the class _internally_, for example, the `toArray()` method is no longer used.\n\n### Creating your first `JSON:API` resource\n\nTo get started, let's create a `UserResource` for our `User` model. In our user resource will expose the user's `name`, `website`, and `twitter_handle` in the response.\n\nFirst we will create a new API resource that extends `TiMacDonald\\JsonApi\\JsonApiResource`.\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Resources;\n\nuse TiMacDonald\\JsonApi\\JsonApiResource;\n\nclass UserResource extends JsonApiResource\n{\n    //\n}\n```\n\n### Adding attributes\n\nWe will now create an `$attributes` property and list the model's attributes we want to expose.\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Resources;\n\nuse TiMacDonald\\JsonApi\\JsonApiResource;\n\nclass UserResource extends JsonApiResource\n{\n    public $attributes = [\n        'name',\n        'website',\n        'twitter_handle',\n    ];\n}\n```\n\nWhen making a request to an endpoint that returns the `UserResource`, for example:\n\n```php\nRoute::get('users/{user}', fn (User $user) =\u003e UserResource::make($user));\n```\n\nThe following `JSON:API` formatted data would be returned:\n\n```json\n{\n  \"data\": {\n    \"type\": \"users\",\n    \"id\": \"74812\",\n    \"attributes\": {\n      \"name\": \"Tim\",\n      \"website\": \"https://timacdonald.me\",\n      \"twitter_handle\": \"@timacdonald87\"\n    }\n  }\n}\n```\n\n🎉 You have just created your first `JSON:API` resource 🎉\n\nCongratulations...and what. a. rush!\n\nWe will now dive into adding relationships to your resources, but if you would like to explore more complex attribute features you may like to jump ahead:\n\n- [`toAttributes()`](#toAttributes)\n- [Sparse fieldsets](#sparse-fieldsets)\n- [Minimal attributes](#minimal-attributes)\n- [Lazy attribute evaluation](#lazy-attribute-evaluation)\n\n### Adding relationships\n\nAvailable relationships may be specified in a `$relationships` property, similar to the [`$attributes` property](#adding-attributes), however you may use a key / value pair to provide the resource class that should be used for the given relationship.\n\nWe will make two relationships available on the resource:\n\n- `$user-\u003eteam`: a \"toOne\" / `HasOne` relationship.\n- `$user-\u003eposts`: a \"toMany\" / `HasMany` relationship.\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Resources;\n\nuse TiMacDonald\\JsonApi\\JsonApiResource;\n\nclass UserResource extends JsonApiResource\n{\n    public $attributes = [\n        'name',\n        'website',\n        'twitter_handle',\n    ];\n\n    public $relationships = [\n        'team' =\u003e TeamResource::class,\n        'posts' =\u003e PostResource::class,\n    ];\n}\n```\n\nAssuming the key / value pair follows the convention `'{myKey}' =\u003e {MyKey}Resource::class`, the class may be omitted to streamline things further.\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Resources;\n\nuse TiMacDonald\\JsonApi\\JsonApiResource;\n\nclass UserResource extends JsonApiResource\n{\n    public $attributes = [\n        'name',\n        'website',\n        'twitter_handle',\n    ];\n\n    public $relationships = [\n        'team',\n        'posts',\n    ];\n}\n```\n\n##### Example request and response\n\nThe client may now request these relationships via the `include` query parameter.\n\n`GET /users/74812?include=posts,team`\n\n\u003e **Note** Relationships are not exposed in the response unless they are requested by the calling client via the `include` query parameter. This is intended and is part of the `JSON:API` specification.\n\n```json\n{\n  \"data\": {\n    \"id\": \"74812\",\n    \"type\": \"users\",\n    \"attributes\": {\n      \"name\": \"Tim\",\n      \"website\": \"https://timacdonald.me\",\n      \"twitter_handle\": \"@timacdonald87\"\n    },\n    \"relationships\": {\n      \"posts\": {\n        \"data\": [\n          {\n            \"type\": \"posts\",\n            \"id\": \"25240\"\n          },\n          {\n            \"type\": \"posts\",\n            \"id\": \"39974\"\n          }\n        ]\n      },\n      \"team\": {\n        \"data\": {\n          \"type\": \"teams\",\n          \"id\": \"18986\"\n        }\n      }\n    }\n  },\n  \"included\": [\n    {\n      \"id\": \"25240\",\n      \"type\": \"posts\",\n      \"attributes\": {\n        \"title\": \"So what is `JSON:API` all about anyway?\",\n        \"content\": \"...\",\n        \"excerpt\": \"...\"\n      }\n    },\n    {\n      \"id\": \"39974\",\n      \"type\": \"posts\",\n      \"attributes\": {\n        \"title\": \"Building an API with Laravel, using the `JSON:API` specification.\",\n        \"content\": \"...\",\n        \"excerpt\": \"...\"\n      }\n    },\n    {\n      \"id\": \"18986\",\n      \"type\": \"teams\",\n      \"attributes\": {\n        \"name\": \"Laravel\"\n      }\n    }\n  ]\n}\n```\n\nTo learn about more complex relationship features you may like to jump ahead:\n\n- [`toRelationships()`](#toRelationships)\n- [Customising the relationship resource class guessing](#customising-the-relationship-resource-class-guessing)\n\n## A note on eager loading\n\nThis package does not [eager load](https://laravel.com/docs/eloquent-relationships#eager-loading) Eloquent relationships. If a relationship is not eagerly loaded, the package will lazy load the relationship on the fly. I _highly_ recommend using [Spatie's query builder](https://spatie.be/docs/laravel-query-builder/) package which will eager load your models against the `JSON:API` query parameter standards.\n\nSpatie provide comprehensive documentation on how to use the package, but I will briefly give an example of how you might use this in a controller.\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Controllers;\n\nuse App\\Http\\Resources\\UserResource;\nuse App\\Models\\User;\nuse Spatie\\QueryBuilder\\QueryBuilder;\n\nclass UserController\n{\n    public function index()\n    {\n        $users = QueryBuilder::for(User::class)\n            -\u003eallowedIncludes(['team', 'posts'])\n            -\u003epaginate();\n\n        return UserResource::collection($users);\n    }\n\n    public function show($id)\n    {\n        $user = QueryBuilder::for(User::class)\n            -\u003eallowedIncludes(['team', 'posts'])\n            -\u003efindOrFail($id);\n\n        return UserResource::make($user);\n    }\n}\n```\n\n## Digging deeper\n\nWe have now covered the basics of exposing attributes and relationships on your resources. We will now cover more advanced topics to give you even greater control.\n\n### Attributes\n\n#### `toAttributes()`\n\nAs we saw in the [adding attributes](#adding-attributes) section, the `$attributes` property is the fastest way to expose attributes for a resource. In some scenarios you may need greater control over the attributes you are exposing. If that is the case, you may implement the `toAttributes()` method. This will grant you access to the current request and allow for conditional logic.\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Resources;\n\nuse TiMacDonald\\JsonApi\\JsonApiResource;\n\nclass UserResource extends JsonApiResource\n{\n    /**\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array\u003cstring, mixed\u003e\n     */\n    public function toAttributes($request)\n    {\n        return [\n            'name' =\u003e $this-\u003ename,\n            'website' =\u003e $this-\u003ewebsite,\n            'twitter_handle' =\u003e $this-\u003etwitter_handle,\n            'email' =\u003e $this-\u003ewhen($this-\u003eemail_is_public, $this-\u003eemail, '\u003cprivate\u003e'),\n            'address' =\u003e [\n                'city' =\u003e $this-\u003eaddress('city'),\n                'country' =\u003e $this-\u003eaddress('country'),\n            ],\n        ];\n    }\n}\n```\n\n##### Example response\n\n```json\n{\n  \"data\": {\n    \"id\": \"74812\",\n    \"type\": \"users\",\n    \"attributes\": {\n      \"name\": \"Tim\",\n      \"website\": \"https://timacdonald.me\",\n      \"twitter_handle\": \"@timacdonald87\",\n      \"email\": \"\u003cprivate\u003e\",\n      \"address\": {\n        \"city\": \"Melbourne\",\n        \"country\": \"Australia\"\n      }\n    }\n  }\n}\n```\n\n#### Sparse fieldsets\n\nSparse fieldsets are a feature of the `JSON:API` specification that allows clients to specify which attributes, for any given resource type, they would like to receive. This allows for more deterministic responses, while also improving server-side performance and reducing payload sizes. Sparse fieldsets work out of the box for your resources.\n\nWe will cover them briefly here, but we recommend reading the specification to learn more.\n\nAs an example, say we are building out an index page for a blog. The page will show each post's `title` and `excerpt`, and also the `name` of the post's author. If the client wishes, they may limit the response to _only_ include the required attributes for each resource type, and exclude the other attributes, such as the post's `content` and the authors `twitter_handle`.\n\nTo achieve this we will send the following request.\n\n```\nGET /posts?include=author\u0026fields[posts]=title,excerpt\u0026fields[users]=name\n```\n\n\u003e **Note** The `include` query parameter key is `author`, while the sparse fieldset parameter key is `users`. This is because authors _are_ users, e.g. the Eloquent `author()` relationship returns a `User` model.\n\n##### Example response\n\n```json\n{\n  \"data\": [\n    {\n      \"id\": \"25240\",\n      \"type\": \"posts\",\n      \"attributes\": {\n        \"title\": \"So what is `JSON:API` all about anyway?\",\n        \"excerpt\": \"...\"\n      },\n      \"relationships\": {\n        \"author\": {\n          \"data\": {\n            \"type\": \"users\",\n            \"id\": \"74812\"\n          }\n        }\n      }\n    },\n    {\n      \"id\": \"39974\",\n      \"type\": \"posts\",\n      \"attributes\": {\n        \"title\": \"Building an API with Laravel, using the `JSON:API` specification.\",\n        \"excerpt\": \"...\"\n      },\n      \"relationships\": {\n        \"author\": {\n          \"data\": {\n            \"type\": \"users\",\n            \"id\": \"74812\"\n          }\n        }\n      }\n    }\n  ],\n  \"included\": [\n    {\n      \"type\": \"users\",\n      \"id\": \"74812\",\n      \"attributes\": {\n        \"name\": \"Tim\"\n      }\n    }\n  ]\n}\n```\n\n#### Minimal attributes\n\nResources return a maximal attribute payload when [sparse fieldsets](#sparse-fieldsets) are not in use i.e. all declared attributes on the resource are returned. If you prefer you can make the use of sparse fieldsets required in order to retrieve _any_ attributes.\n\nYou may call the `useMinimalAttributes()` method in an application service provider.\n\n```php\n\u003c?php\n\nnamespace App\\Providers;\n\nuse Illuminate\\Support\\ServiceProvider;\nuse TiMacDonald\\JsonApi\\JsonApiResource;\n\nclass AppServiceProvider extends ServiceProvider\n{\n    public function boot()\n    {\n        JsonApiResource::useMinimalAttributes();\n\n        // ...\n    }\n}\n```\n\n#### Lazy attribute evaluation\n\nFor attributes that are expensive to calculate, it is possible to have them evaluated _only_ when they are to be included in the response, i.e. they have not been excluded via [sparse fieldsets](#sparse-fieldsets) or [minimal attributes](#minimal-attributes). This may be useful if you are interacting with a database or making HTTP requests in a resource.\n\nAs an example, let's imagine that we expose a base64 encoded avatar for each user. Our implementation downloads the avatar from our in-house avatar microservice.\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Resources;\n\nuse Illuminate\\Support\\Facades\\Http;\nuse TiMacDonald\\JsonApi\\JsonApiResource;\n\nclass UserResource extends JsonApiResource\n{\n    /**\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array\u003cstring, mixed\u003e\n     */\n    public function toAttributes($request)\n    {\n        return [\n            // ...\n            'avatar' =\u003e Http::get(\"https://avatar.example.com/{$this-\u003eid}\")-\u003ebody(),\n        ];\n    }\n}\n```\n\nThe above implementation would make a HTTP request to our microservice even when the client is excluding the `avatar` attribute via sparse fieldsets or minimal attributes. To improve performance when this attribute is not being returned we can wrap the value in a `Closure`. The `Closure` will only be evaluated when the `avatar` is to be returned.\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Resources;\n\nuse Illuminate\\Support\\Facades\\Http;\nuse TiMacDonald\\JsonApi\\JsonApiResource;\n\nclass UserResource extends JsonApiResource\n{\n    /**\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array\u003cstring, mixed\u003e\n     */\n    public function toAttributes($request)\n    {\n        return [\n            // ...\n            'avatar' =\u003e fn () =\u003e Http::get(\"https://avatar.example.com/{$this-\u003eid}\")-\u003ebody(),\n        ];\n    }\n}\n```\n\n### Relationships\n\n#### `toRelationships()`\n\nAs we saw in the [adding relationships](#adding-relationships) section, the `$relationships` property is the fastest way to specify the available relationships for a resource. In some scenarios you may need greater control over the relationships you are making available. If that is the case, you may implement the `toRelationships()` method. This will grant you access to the current request and allow for conditional logic.\n\nThe value must always be wrapped in a `Closure`, which will only be called if the relationships is requested by the client.\n\n```php\n\u003c?php\n\nnamespace App\\Http\\Resources;\n\nuse TiMacDonald\\JsonApi\\JsonApiResource;\n\nclass UserResource extends JsonApiResource\n{\n    /**\n     * @param  \\Illuminate\\Http\\Request  $request\n     * @return array\u003cstring, (callable(): \\TiMacDonald\\JsonApi\\JsonApiResource|\\TiMacDonald\\JsonApi\\JsonApiResourceCollection|\\Illuminate\\Http\\Resources\\PotentiallyMissing)\u003e\n     */\n    public function toRelationships($request)\n    {\n        return [\n            'team' =\u003e fn () =\u003e TeamResource::make($this-\u003eteam),\n            'posts' =\u003e fn () =\u003e $request-\u003euser()-\u003eis($this-\u003eresource)\n                ? PostResource::collection($this-\u003eposts)\n                : PostResource::collection($this-\u003eposts-\u003ewhere('published', true)),\n        ];\n    }\n}\n```\n\n#### Customising the relationship resource class guessing\n\n```php\n\n```\n\n//----- Everything that follows is WIP and should be ignored ------- //\n\n## Resource Identification\n\n`[JSON:API` docs: Identification](https://jsonapi.org/format/#document-resource-object-identification)\n\nWe have defined a sensible default for you so you can hit the ground running without having to fiddle with the small stuff.\n\nThe `\"id\"` and `\"type\"` of a resource is automatically resolved for you under-the-hood if you are using resources solely with Eloquent models.\n\n`\"id\"` is resolved by calling the `$model-\u003egetKey()` method and the `\"type\"` is resolved by using a camel case of the model's table name, e.g. `blog_posts` becomes `blogPosts`.\n\nYou can customise how this works to support other types of objects and behaviours, but that will follow in the [advanced usage](#advanced-usage) section.\n\nNice. Well that was easy, so let's move onto...\n\n## Resource Links\n\n`[JSON:API` docs: Links](https://jsonapi.org/format/#document-resource-object-links)\n\nTo provide links for a resource, you can implement the `toLinks($request)` method...\n\n```php\n\u003c?php\n\nuse TiMacDonald\\JsonApi\\Link;\n\nclass UserResource extends JsonApiResource\n{\n    public function toLinks($request): array\n    {\n        return [\n            Link::self(route('users.show', $this-\u003eresource)),\n            'related' =\u003e 'https://example.com/related'\n        ];\n    }\n}\n```\n\n## Resource Meta\n\n`[JSON:API` docs: Meta](https://jsonapi.org/format/#document-meta)\n\nTo provide meta information for a resource, you can implement the `toMeta($request)` method...\n\n```php\n\u003c?php\n\nclass UserResource extends JsonApiResource\n{\n    public function toMeta($request): array\n    {\n        return [\n            'resourceDeprecated' =\u003e true,\n        ];\n    }\n}\n```\n\n# Advanced usage\n\n## Resource Identification\n\n### Customising the resource `\"id\"`\n\nYou can customise the resolution of the `id` by specifying an id resolver in your service provider.\n\n```php\n\u003c?php\n\nclass AppServiceProvider extends ServiceProvider\n{\n    public function boot()\n    {\n        JsonApiResource::resolveIdUsing(function (mixed $resource, Request $request): string {\n            // your custom resolution logic...\n        });\n    }\n}\n```\n\nAlthough it is not recommended, you can also override the `toId(Request $request): string` method on a resource by resource basis.\n\n### Customising the resource `\"type\"`\n\nYou can customise the resolution of the `type` by specifying a type resolver in your service provider.\n\n```php\n\u003c?php\n\nclass AppServiceProvider extends ServiceProvider\n{\n    public function boot()\n    {\n        JsonApiResource::resolveTypeUsing(function (mixed $resource, Request $request): string {\n            // your custom resolution logic...\n        });\n    }\n}\n```\n\nAlthough it is not recommended, you can also override the `toType(Request $request): string` method on a resource by resource basis.\n\n## Resource Relationships\n\n`[JSON:API` docs: Inclusion of Related Resources](https://jsonapi.org/format/#fetching-includes)\n\nRelationships can be resolved deeply and also multiple relationship paths can be included. Of course you should be careful about n+1 issues, which is why we recommend using this package in conjunction with [Spatie's Query Builder](https://github.com/spatie/laravel-query-builder/).\n\n```sh\n# Including deeply nested relationships\n/api/posts/8?include=author.comments\n\n# Including multiple relationship paths\n/api/posts/8?include=comments,author.comments\n```\n\n- Using \"whenLoaded is an anti-pattern\"\n\n## Credits\n\n- [Tim MacDonald](https://github.com/timacdonald)\n- [Jess Archer](https://github.com/jessarcher) for co-creating our initial in-house version and the brainstorming\n- [All Contributors](../../contributors)\n\nAnd a special (vegi) thanks to [Caneco](https://twitter.com/caneco) for the logo ✨\n\n# v1 todo\n- Server implementation rethink.\n- Rethink naming of objects and properties\n- Camel case everything\n- Allow resources to specify their JsonResource class.\n- Make all caches WeakMaps.\n- Things that \"must\" need to be first in the __consstructor. See Links:href\n- Should it be withResourceIdentifier or mapResourceIdentifier. Feel like we are mapping. or pipeResourceIdentifier\n- Should all caches use weakmap with request key?\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimacdonald%2Fjson-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftimacdonald%2Fjson-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftimacdonald%2Fjson-api/lists"}