All notable changes to this project will be documented in this file. This project adheres to Semantic Versioning and this changelog format.
- Updated to support PHP
7.4
(minimum PHP remains7.1
).
- #440 Amend query method signature on validated request to match Laravel request signature.
- #445 Allow resource identifier to be zero.
- #447 Ensure deserialized attributes do not include relations if the relation has been sent as an attribute.
- #415 Added a has-one-through JSON API resource relationship for the Eloquent has-one-through relationship that was added in Laravel 5.8.
- #439
Fixed tests failing in Laravel
^6.1
. Applications using Laravel 6 need to upgrade the JSON API testing package to^2.0
as follows:
$ composer require --dev cloudcreativity/json-api-testing:^2.0
- Package now supports Laravel 6.
- #333
Eloquent adapters now have a
filterWithScopes()
method, that maps JSON API filters to model scopes and the Eloquentwhere*
method names. This is opt-in: i.e. to use, the developer must callfilterWithScopes()
within their adapter'sfilter()
method. - Added
put
,putAttr
andputRelation
methods to theResourceObject
class.
- Updated Travis config for Laravel
5.9
being renamed6.0
. - #400 Fix overridden variable in error translator.
- #352 Can now set an API's default controller name to the singular version of the resource type.
- Can now register a callback for resolving a controller name from a resource type.
- #373 Can now change the JSON API controller's default connection and whether it uses transactions via an API's config.
- #377 Can now toggle the simple pagination strategy back to using length aware pagination.
- #380
Can now customise the conversion of a resource id to a database id on an adapter by overloading the
databaseId()
method. - New
HasOne
andHasMany
rule objects for validating that a relationship is to-one or to-many, and has the expected resource type(s). - #391
Allow the validators
existingRelationships()
method to return the existing related records, and automatically convert these to JSON API identifiers.
- #371 Ensure Eloquent delete/deleting events are fired when soft-deleting a resource.
- Eloquent adapter hooks will now be invoked when force-deleting a resource that uses
the
SoftDeletesModels
trait.
- #360 Allow soft delete attribute path to use dot notation.
- Added
domain
method to API fluent routing methods. - #337 Can now apply global scopes to JSON API resources via adapter scopes.
- #370 Fix wrong validation error title when creating a custom validator.
- #369
Fix using an alternative decoding type for update (
PATCH
) requests. - #362 Fix fatal error in route class caused by polymorphic entity types.
- #358
Queue listener could trigger a
ModelNotFoundException
when deserializing a job that had deleted a model during itshandle()
method. - #347
Update
zend-diactoros
dependency.
- #315 Allow developers to use the exact JSON API field name as the relationship method name on their adapters, plus for default conversion of names in include paths. Although we recommend following the PSR1 standard of using camel case for method names, this does allow a developer to use snake case field names with snake case method names.
- Exception handlers can now use the
parseJsonApiException()
helper method if they need to convert JSON API exceptions to HTTP exceptions. Refer to the installation instructions for an example of how to do this on an exception handler.
- #329
Render JSON API error responses when a codec has matched, but the client has not explicitly
asked for JSON API response (e.g. asked for
Accept: */*
). - #313 Ensure that the standard paging strategy uses the resource identifier so that pages have a deterministic sort order.
- A
303 See Other
will now not be returned if a client job has failed. This is necessary because otherwise there is no way for an API client to determine that the job completed but failed.
- Package now supports Laravel 5.8.
- #302
Reject resource objects sent in relationships, as the spec defines that only resource identifiers
are expected. This is based on the object having either an
attributes
or arelationships
member. - #295
Use
null
for emptyfrom
/to
fields in cursor page meta.
- #265
Allow wildcard media type parameters when matching decodings. Allows
multipart/form-data; boundary=*
to be accepted for decoding purposes.
- #271 Can now validate delete resource requests.
- #196 Can now add custom actions to resource controllers. Refer to the Routing and Controllers chapters.
- #242 Can now override the default controller for an API. Refer to the Controllers chapter for details.
- #289
Can now opt-in to Laravel validation failure data being added to the
meta
member of JSON API error objects.
- #254 Refactored content negotiation so that multiple media types can be supported. Refer to the Media Types documentation for details.
- Simplified the validator classes into a single class:
Validators\Validator
. - Renamed a lot of classes in the
Routing
namespace. They are also marked asfinal
because they are not meant to be extended. - Modified the abstract
mount
method that package providers use to add routes to an API. Also added PHP 7 type-hinting to all methods in the abstract class.
- #265
Allow wildcard media type parameters when matching decoders. This enables support for media types that
include random parameter values, primarily the
multipart/form-data
type that has aboundary
parameter that is unpredictable. - #280 Validation error objects for relationship objects now have correct source pointers.
- #284 Content negotiation middleware no longer causes a container binding exception when the Kernel is terminated.
- The following classes in the
Validation
namespace were removed as theValidation\Validator
class can be used instead, or validators can be constructed via the factory instead:AbstractValidator
ResourceValidator
QueryValidator
- The deprecated
EloquentController
was removed - extendJsonApiController
directly. - The
Store\EloquentAdapter
was removed - extendEloquent\AbstractAdapter
directly. - The following previously deprecated methods/properties were removed from the
EloquentAdapter
:- public method
queryRelation()
: renamedqueryToMany()
. - protected property
$with
: renamed$defaultWith
. - protected method
keyForAttribute()
: renamedmodelKeyForField()
. - protected method
columnForField()
: renamedgetSortColumn()
. - protected method
all()
: renamedsearchAll()
. - protected method
extractIncludePaths()
: overload thegetQueryParameters()
method instead. - protected method
extractFilters()
: overload thegetQueryParameters()
method instead. - protected method
extractPagination()
: overload thegetQueryParameters()
method instead.
- public method
- The previously deprecated
Eloquent\Concerns\AbstractRelation
class was removed. ExtendAdapter\AbstractRelationshipAdapter
and use theEloquent\Concerns\QueriesRelations
trait. - Removed the deprecated
Contracts\Utils\ConfigurableInterface
as this has not been in use for some time. - Removed the deprecated
createResourceDocumentValidator()
method from the factory. - Removed the following previously deprecated methods from the
TestResponse
class:assertJsonApiResponse()
: usejsonApi()
.normalizeIds()
andnormalizeId()
as these are not in use by the refactored test implementation.
- Removed the following previously deprecated methods from the JSON API service/facade:
report()
: no longer supported for access via the service.requestOrFail()
: no longer required.
- Removed the previously deprecated
Schema\ExtractsAttributesTrait
as it has not been used for some time.
- #277 Eloquent adapter can now support soft-deleting, restoring and force-deleting resources by applying a trait to the adapter. See the soft-deletes documentation chapter for details.
- #247 New date time rule object to validate a JSON date string is a valid ISO 8601 date and time format.
- #261 Package now supports the JSON API recommendation for asynchronous processing. See the Asynchronous Processing chapter for details.
- #267 New adapter hooks are invoked to allow either the filling of additional attributes or dispatching asynchronous processes from within an adapter.
- #246 Can now disable providing the existing resource attributes to the resource validator for an update request.
- Added an
existingRelationships
method to the abstract validators class. Child classes can overload this method if they need the validator to have access to any existing relationship values for an update request. - JSON API specification validation will now fail if the
attributes
orrelationships
members havetype
orid
fields. - JSON API specification validation will now fail if the
attributes
andrelationships
members have common field names, as field names share a common namespace. - Can now return
Responsable
instances from controller hooks.
- #248 Adapters now receive the JSON API document (HTTP content) as an array.
- #278
The adapter's
read
method now receives the record being read as its first argument rather than the resource ID. This makes it consistent with all other adapter methods that receive the record being read. - Renamed
Http\Requests\IlluminateRequest
toHttp\Requests\JsonApiRequest
. - The
getJsonApi()
test helper method now only has two arguments: URI and headers. Previously it accepted data as the second argument. - Improved test assertions and tidied up the test response class. Also added PHP 7 type-hinting to the methods.
- Improve the store aware trait so that it returns a store even if one has not been injected.
- Encoding parameters are now resolved as a singleton in the Laravel container and are bound into the responses factory even in custom routes.
- The responses factory
error
method now only creates a response for a single error. For multi-error responses, theerrors
method should be used.
- #201 Adapters now receive the array that has been transformed by Laravel's middleware, e.g. trim strings.
- Legacy validators now correctly receive the record when validating a document for an update resource
or update relationship request. This matches previous behaviour which was removed by accident in
beta.4
. - #255 Fix invalid pointer for a required resource field when the client does not supply the field.
- #273 Responses class now correctly passes an array of errors to the error repository.
- #259
If a client sends a client-generated ID for a resource that does not support client-generated IDs, a
403 Forbidden
response will be sent, as defined in the JSON API spec.
- The deprecated
Contracts\Store\AdapterInterface
was removed. UseContracts\Adapter\ResourceAdapterInterface
instead. - The deprecated
Adapter\HydratesAttributesTrait
was removed. - The
Contracts\Http\Requests\RequestInterface
was removed as it is no longer necessary (because the package is no longer framework-agnostic). - Removed the
Contracts\Repository\SchemasRepositoryInterface
andRepository\SchemasRepository
class because these were not in use. - The previously deprecated
InteractsWithModels
testing trait was removed. - The following (majority previously deprecated methods) on the
TestResponse
class were removed:assertDocument
assertResourceResponse
assertResourcesResponse
assertRelatedResourcesResponse
assertSearchResponse
assertSearchOneResponse
assertCreateResponse
assertReadResponse
assertUpdateResponse
assertDeleteResponse
assertRelatedResourceResponse
assertHasOneRelationshipResponse
assertDataCollection
assertDataResource
assertDataResourceIdentifier
assertSearchByIdResponse
assertSearchedPolymorphIds
assertReadPolymorphHasMany
- All interfaces in the
Contracts\Object
namespace will be removed for2.0
. - All classes in the
Object
namespace will be removed for2.0
. - A number of methods on the
MakesJsonApiRequests
andTestResponse
classes have been deprecated as they are better named equivalents or they are not applicable to the current testing approach. These will be removed in2.0
.
- #240 Ensure PHP class name is passed to authorizer when authorizing fetch-many and create resource requests.
- New validation implementation that uses Laravel validators throughout. See the validation documentation for details.
- Errors for the new validation implementation now have their
title
,detail
andcode
members translated via Laravel's translator. This means consuming applications can change the messages by overriding the default translations provided by this package. - #234 HTTP exception headers are now added to the JSON API response when converting to JSON API errors.
- Minimum PHP version is now
7.1
. - Minimum Laravel version is now
5.5
. - The validated request object is now abstract, with a concrete implementation for each type of request.
- #237 The route key name is now used as the default cursor key name.
- The
Auth\HandlesAuthorizers
trait was removed and its logic moved into theAuthorize
middleware.
- The previous validation solution is deprecated in favour of the new solution and will be removed at
2.0
. - The error factory implementation is deprecated in favour of using Laravel translation and will be removed at
2.0
. - The
Document\Error
andContracts\Document\MutableErrorInterface
are deprecated and will be removed at2.0
. You should use the error interface/class from theneomerx/jsonapi
package instead. - The following utility classes/traits/interfaces are deprecated and will be removed at
2.0
:Utils/ErrorCreatorTrait
Utils/ErrorsAwareTrait
andContracts\Utils\ErrorsAwareInterface
Utils/Pointers
Utils/Replacer
andContracts\Utils\ReplacerInterface
- The
Contracts\Factories\FactoryInterface
is deprecated and will be removed at1.0
. You should type-hintFactories\Factory
directly instead.
- New cursor-based paging strategy, refer to the Pagination docs for details.
- Refactored the client interface and implementation, improving record serializing and adding missing relationship request methods.
- #123 Can now use a custom resolver if wanting to override the default namespace resolution provided by this package. This is documented in the Resolvers chapter.
- Extract model sorting from the Eloquent adapter into a
SortsModels
trait. - #144 Improved the helper method that creates new client instances so that it automatically adds a base URI for the client if one is not provided.
- #222
Adding related resources to a has-many relationship now does not add duplicates. The JSON API
spec states that duplicates must not be added, but the default Laravel behaviour does add duplicates.
The
HasMany
relationship now takes care of this by filtering out duplicates before adding them.
- The following methods on the Eloquent adapter will be removed in
1.0.0
as they are no longer required:extractIncludePaths
extractFilters
extractPagination
columnForField
: usegetSortColumn
instead.
- Can now use Eloquent query builders as resource relationships using the
queriesOne
orqueriesMany
JSON API relations. - Custom relationships can now extend the
Adapter\AbstractRelationshipAdapter
class.
- JSON API document is now only parsed out of the request if data is expected within the document. This ensures that Laravel's get JSON test helpers can be used.
- Extracted common Eloquent relation querying methods to the
Eloquent\Concerns\QueriesRelations
trait.
- The
Eloquent\AbstractRelation
class is deprecated and will be removed in1.0.0
. Use the newAdapter\AbstractRelationshipAdapter
class and apply theQueriesRelations
trait. - The
Adapter\HydratesAttributesTrait
is deprecated as it is no longer in use and will be removed in1.0.0
.
- Package now supports Laravel 5.4 to 5.7 inclusive.
- #210 Can now map a single JSON API path to multiple Eloquent eager load paths.
- #218
Can now filter a request for a specific resource, e.g.
/api/posts/1?filter['published']=1
. - Filtering Eloquent resources using the
id
filter is now also supported on to-many and to-one relationships. - Can now set default sort parameters on an Eloquent adapter using the
$defaultSort
property.
- #184 Eloquent route keys are now used as the resource id by default.
- The following deprecated methods have been removed from the Eloquent adapter:
first
: usesearchOne
instead.
- The follow methods are deprecated on the Eloquent adapter and will be removed in
1.0.0
:queryRelation
: usequeryToMany
orqueryToOne
instead.
- #185
Rename adapter
store
method togetStore
to avoid collisions with relation methods. - #187 Ensure hydration of Eloquent morph-many relationship works.
- #194 Ensure encoding parameters are validated when reading a specific resource.
- Exception messages are no longer pushed into the JSON API error detail member, unless the Exception is a HTTP Exception.
- #219
Can now use the
id
filter as one of many filters, previously theid
filter ignored any other filters provided. It now also respects sort and paging parameters.
- #203 JSON API container now checks whether there is a Laravel container binding for a class name. This allows schemas, adapters etc to be bound into the container rather than having to exist as actual classes.
- #202 When appending the schema and host on a request, the base URL is now also appended. This caters for Laravel applications that are served from host sub-directories.
- Errors that occur before a route is processed by a JSON API are now sent to the client as JSON API
error responses if the client wants a JSON API response. This is determined using the
Accept
header and means that exceptions such as the maintenance mode exception are correctly returned as JSON API errors if that is what the client wants. - Can now override the default API name via the JSON API facade.
- Field guarding that was previously available on the Eloquent adapter is now also available on the generic adapter.
- Extracted the logic for an Eloquent
hasManyThrough
relation into its own relationship adapter (was previously in thehas-many
adapter). - Moved the
FindsManyResources
trait from theStore
namespace toAdapter\Concerns
. - The
hydrateRelationships
method on theAbstractResourceAdapter
is no longer abstract as it now contains the implementation that was previously on the Eloquent adapter. - The test exception handler has been moved from the dummy app to the
Testing
namespace. This means it can now be used when testing JSON API packages. - Merged the two resolvers provided by this package into a single class.
- #176
When using not-by-resource resolution, the type of the class is now appended to the class name. E.g.
App\JsonApi\Adapters\PostAdapter
is now expected instead ofApp\JsonApi\Adapters\Post
. The previous behaviour can be maintained by setting theby-resource
config option to the stringfalse-0.x
. - The constructor dependencies for the
Repositories\ErrorRepository
have been simplified.
- Resolver was not correctly classifying the resource type when resolution was not by resource.
- #176 Do not import model class in Eloquent adapter stub to avoid collisions with class name when using the legacy not-by-resource behaviour.
- An exception is no longer triggered when create JSON API responses when there is no booted JSON API handling the request.
- #181 Send a
419
error response with an error object for aTokenMismatchException
. - #182 Send a
422
error response with JSON API error objects when aValidationException
is thrown outside of JSON API validation.
- The
report
method on the JSON API service/facade will be removed by1.0.0
.
- New authorizer interface and an abstract class that better integrates with Laravel's authentication and authorization style. See the new Security chapter for details.
- Can now generate authorizers using the
make:json-api:authorizer
command, or the--auth
flag when generating a resource withmake:json-api:resource
. - The JSON API controller now has the following additional hooks:
searching
for an index action.reading
for a read action.
- #163 Added relationship hooks to the JSON API controller.
- Generating an Eloquent schema will now generate a class that extends
SchemaProvider
, i.e. the generic schema. - Existing JSON API controller hooks now receive the whole validated JSON API request rather than just the resource object submitted by the client.
- The previous authorizer implementation has been removed in favour of the new one. The following were deleted:
Contract\Authorizer\AuthorizerInterface
Authorizer\AbstractAuthorizer
Authorizer\ReadOnlyAuthorizer
Exceptions\AuthorizationException
- Eloquent schemas are now deprecated in favour of using generic schemas. This is because of the amount of
processing involved without any benefit, as generic schemas are straight-forward to construct. The following
classes/traits are deprecated:
Eloquent\AbstractSchema
Eloquent\SerializesModels
Schema\CreatesLinks
Schema\EloquentSchema
(was deprecated in1.0.0-alpha.1
).
As we are now only developing JSON API within Laravel applications, we have deprecated our framework agnostic
cloudcreativity/json-api
package. All the classes from that package have been merged into this package and
renamed to the CloudCreativity\LaravelJsonApi
namespace. This will allow us to more rapidly develop this
Laravel package and simplify the code in subsequent releases.
- New Eloquent relationship adapters allows full support for relationship endpoints.
- Message bags can now have their keys mapped and/or dasherized when converting them to JSON API errors
in the
ErrorBag
class. - JSON API resource paths are now automatically converted to model relationship paths for eager loading in the Eloquent adapter.
- The Eloquent adapter now applies eager loading when reading or updating a specific resource.
- Eloquent adapters can now guard JSON API fields via their
$guarded
and$fillable
properties. These are used when filling attributes and relationships. - Added standard serialization of relationships within Eloquent schemas. This always serializes
self
andrelated
links for listed model relationships, and only adds the relationshipdata
if the relationship is being included in a compound document.
- By default resources no longer need to have a controller as the generic JSON API controller will now
handle any resource. If resources have controllers, the
controller
routing option can be set to a string controller name, ortrue
to use a controller with the same name as the resource. - Split adapter into resource and relationship adapter, and created classes to specifically deal with Eloquent relationships.
- Adapters now handle both reading and modifying domain records.
- Moved Eloquent JSON API classes into a single namespace.
- Moved logic from Eloquent controller into the JSON API controller as the logic is no longer specific to handling resources that related to Eloquent models.
- Filter, sort and page query parameters are no longer allowed for requests on primary resources (create, read update and delete) because these query parameters do not apply to these requests.
- When serializing Eloquent models, if no attributes are specified for serialization (a
null
value), onlyModel::getVisible()
will now be used to work out what attributes must be serialized. Previously ifgetVisible
returned an empty array,getFillable
would be used instead.
- Delete Eloquent hydrator class as all hydration is now handled by adapters instead.
- The utility
Fqn
class has been removed as namespace resolution is now done by resolvers. - The deprecated
Str
utility class has been removed. UseCloudCreativity\JsonApi\Utils\Str
instead.
- The Eloquent controller is deprecated in favour using the JSON API controller directly.
- The
Schema\EloquentSchema
is deprecated in favour of using theEloquent\AbstractSchema
. - The
Store\EloquentAdapter
is deprecated in favour of using theEloquent\AbstractAdapter
. - The
Testing\InteractsWithModels
trait is deprecated in favour of Laravel database assertion helpers. - The
ErrorBag::toArray
method is deprecated in favour ofErrorBag::all
. - The
Schema\CreatesEloquentIdentities
trait is deprecated.
- #128 Filter, sort and page parameters validation rules are excluded for resource requests for which those parameters do not apply (create, read, update and delete).
- #92 Last page link is now excluded if there are pages, rather than linking to page zero.
- #67 Pagination meta will no longer leak into error response if error occurs when encoding data.
- #111 Sending an invalid content type header now returns a JSON API error object.
- #146 Return a 404 JSON API error object and allow this to be overridden.
- #155 Return a JSON API error when the request content cannot be JSON decoded.
- #169
Generating a resource when the
by-resource
option was set tofalse
had the wrong class name in the generated file.