api-platform / core Goto Github PK
View Code? Open in Web Editor NEWThe server component of API Platform: hypermedia and GraphQL APIs in minutes
Home Page: https://api-platform.com
License: MIT License
The server component of API Platform: hypermedia and GraphQL APIs in minutes
Home Page: https://api-platform.com
License: MIT License
When serializing trees with groups such as the following, it is convenient to be able to configure the Serialization depth:
class TreeEntry
{
/**
* @var TreeEntry
* @Groups{"a"}
*/
public $parent;
}
A new @Depth(n)
where N is the maximum depth level to normalize can be useful for such use case. When n
is reached, the normalizer will output the IRI of the resource instead of embedding it. Proposal:
class TreeEntry
{
/**
* @var TreeEntry
* @Groups{"a"}
* @Depth(2)
*/
public $parent;
}
For example : on user creation i set the password field (POST operation). But i want to remove the possibility of modifying this field on PUT / PATCH operations.
There is an existing feature or a trick to do this actually ?
I'm a little stuck and I really don't get what's wrong in my config.
I installed a dunglas/api-platform project with FOSUserBundle. I declared my own User
, which extends the FOSUserBundle entity, as a resource to expose it to my API. So far so good, if I request GET /api/users
I get the expected result.
Now I add use Symfony\Component\Serializer\Annotation\Groups;
to my Entity
class and use the annotation @Groups({"user"})
to properties I which to expose to my API. The properties are properly redeclared as protected. Then in my service.yml
I add:
calls:
- [ "initNormalizationContext", [ { groups: [ "user" ] } ] ]
But the result is that no properties are exposed, I only get the @id
and @type
properties.
Any idea from where the error may come from?
As of now we have three native filters:
?property=value
?order[property]=<asc|desc>
?property[<before|after>]=value
In the process we added the Dunglas\ApiBundle\Doctrine\Orm\AbstractFilter
class to do some refactoring. Still, as discussed, there still some redundancy and maybe more logic could be moved into the AbstractFilter
.
Besides the main issue one could meet with those filter is:
filter[where][property][op]=value&filter[order][property]=<asc|desc>
To do so, we could try to keep the same pattern used in Dunglas\ApiBundle\Doctrine\Orm\OrderFilter
which is dividing the Filter::apply()
method in two: Filter::apply()
and Filter::applyFilter()
. The later would take an array of values and implement the behavior of the filter while the first would retrieve the values and pass them to the second method. Another way would be as you suggested to use a Closure to do so. The gist of it is to provide a way to easily extend a filter to tackle one of the two issue mentioned above.
Other notes:
properties
protected or add a getter otherwise requires to redeclare it when overriding getDescription
When using two "IDs": one is the real ID for the database and the other is the ID exposed to the API, for example with an entity User
for which the database ID is id
and the "API ID" is username
, the DataProvider
should be extendable or have the necessary operations to avoid any dumb copy/paste.
Would it be possible to make the properties and functions of DataProvider
protected
instead of private
or it has been made so on purpose?
Actualy name converter is used in (de)normalization of the object.
But it should also be used in several locations:
"violations": [
{
"message": "This value should not be blank.",
"propertyPath": "content" <== here
}
]
http://localhost:8000/api/offers?price=10
price should be denormalized/offers?order[name]=desc&order[id]=asc
.In the README.md
, the property initSerializationContext
, which does not exists is used instead of initNormalizationContext
.
The 10th place for the Controller
chapter seems a bit far. And there is a little error with the link of the previous chapter for the Controller.
As seen with @dunglas it would be great to enable filters on embedded relations.
Exemple:
services:
resource.dummy.search_filter:
parent: api.doctrine.orm.search_filter
arguments:
-
dummyRelation.slug: exact # enable to use search filter on slug property of the target entity
And then to use the search filter on it: ?dummyRelation.slug=value
.
The same way for the date and order filter:
?dummyRelation.dummyDate[before]=value
?order[dummyRelation.dummyDate]=asc
Could it be possible to tag the following commits:
SearchFilter
and we had to extend the DataProvider
for adding custom filters. Not particularly useful but would for everyone but still more practical for our project.Of course since the bundle is still in development, the tags could be 0.X which is well handled by Composer.
In extract of Yaml code (ex: disabling-operations), you indent the code as the following:
services:
resource.product.collection_operation.get:
class: "Dunglas\JsonLdApiBundle\Api\Operation\Operation"
public: false
factory: [ "@api.operation_factory", "createItemOperation" ]
arguments: [ "@resource.product", "GET" ]
resource.product:
parent: "api.resource"
arguments: [ "AppBundle\Entity\Product" ]
- [ "addCollectionOperation", [ "@resource.product.collection_operation.get" ] ]
tags: [ { name: "api.resource" } ]
While the result is clean and pretty, the space between the key and the value is far too big and result in two things:
Maybe keeping the indentation as follow would be a better although less pretty (at least IMO):
services:
resource.product.collection_operation.get:
class: "Dunglas\JsonLdApiBundle\Api\Operation\Operation"
public: false
factory: [ "@api.operation_factory", "createItemOperation" ]
arguments: [ "@resource.product", "GET" ]
resource.product:
parent: "api.resource"
arguments: [ "AppBundle\Entity\Product" ]
- [ "addCollectionOperation", [ "@resource.product.collection_operation.get" ] ]
tags: [ { name: "api.resource" } ]
And maybe remove unnecessary "
:
services:
resource.product.collection_operation.get:
class: Dunglas\JsonLdApiBundle\Api\Operation\Operation
public: false
factory: [ @api.operation_factory, createItemOperation ]
arguments: [ @resource.product, GET ]
resource.product:
parent: api.resource
arguments: [ AppBundle\Entity\Product ]
- [ addCollectionOperation, [ @resource.product.collection_operation.get ] ]
tags: [ { name: api.resource } ]
Or does it causes any error?
It would be great to have some tools to ease the development and debug of filters, for starter:
I guess it won't be a priority but I still find it worth being mentioned.
At first I added this in #70 but I moved it here since it's a different problem although related.
So to sum it up another use case which might happen quite often is to look for "empty" values. I quote the word "empty" since its meaning is a little bit ambigus. Indeed in PHP a value is empty if undefined
, null
or a value equivalent to false
. For this case I'm talking refering to a value equivalent to false
which is not null.
As seen with StrongLoop test in #70, to search for empty value: ?filter[where][property]
or ?filter[where][property]=
Values matching the criteria for each types, nothing surprising of course:
""
0
Invalid date
false
As of now, ?property
or ?property=
is silently ignored from our filters. Would it be possible to change this to look for an empty value instead?
Imagine you have a "Country" (http://schema.org/Country) resource in your API.
How to manage i18N on it ?
Here is a detailed solution, i have design based on experience, and the JSON-LD spec.
Tell me if you think this is a good idea ?
If you think it's not ... tell me why ?
Add a GET specific parameter "locale"
Why ?
GET http://api.example.com/countries/1
{
"@context": {
"@base" : "http://schema.org",
"name" : {
"@container": "@language"
}
},
"@type": "Country",
"@id": "/countries/1",
"name": {
"fr-FR" : "Angleterre",
"en" : "England"
}
}
=> Will return resource with all locale data
GET http://api.example.com/countries/1?locale=fr-FR
{
"@context": "http://schema.org",
"@type": "Country",
"@id": "/countries/1",
"@language": "fr-FR",
"name": "Angleterre"
}
=> Will return resource with requested locale
Note we use locale (on request + response) in W3C format (IETF's BCP 47), see http://www.w3.org/International/articles/language-tags/
It's the format used also with JSON-LD.
GET http://api.example.com/countries/1?locale=es-CA
{
"@context": "/contexts/LocalizationError",
"@type": "LocalizationError",
"hydra:title": "An error occurred",
"hydra:description": "no localization found for locale es-CA"
}
=> Will return code "404 not found", because es-CA localization don't exist in my api.
same as for one resource
GET http://api.example.com/countries
{
"@context": {
"@base" : "http://schema.org",
"name" : {
"@container": "@language"
}
},
"@id": "/countries",
"@type": "hydra:PagedCollection",
"hydra:totalItems": 1,
"hydra:itemsPerPage": 3,
"hydra:firstPage": "/countries",
"hydra:lastPage": "/countries",
"hydra:member": [
{
"@type": "Country",
"@id": "/countries/1",
"name": {
"fr-FR" : "Angleterre",
"en" : "England"
}
}
]
}
=> Will return resources with all available localization
GET http://api.example.com/countries?locale=fr-FR
{
"@context": "http://schema.org",
"@id": "/countries",
"@type": "hydra:PagedCollection",
"@language": "fr-FR",
"hydra:totalItems": 1,
"hydra:itemsPerPage": 3,
"hydra:firstPage": "/countries",
"hydra:lastPage": "/countries",
"hydra:member": [
{
"@type": "Country",
"@id": "/countries/1",
"name": "Angleterre"
}
]
}
=> Will return resource with requested locale
GET http://api.example.com/countries?locale=es-CA
{
"@context": "http://schema.org",
"@id": "/countries",
"@type": "hydra:PagedCollection",
"@language": "es-CA",
"hydra:totalItems": 0,
"hydra:itemsPerPage": 3,
"hydra:firstPage": "/countries",
"hydra:lastPage": "/countries",
"hydra:member": []
}
same as usual but the localization are also deleted completely
DELETE http://api.example.com/countries/1
=> Will delete country and all associed localization
DELETE http://api.example.com/countries/1?locale=fr-FR
=> Will delete country localization fr-FR only !
create with a locale container or indicate the language in context
POST http://api.example.com/countries
{
"name": {
"fr-FR" : "Angleterre",
"en": "England"
}
}
=> Will create country with two localized value
OR
POST http://api.example.com/countries
{
"@context": {
"@language": "fr-FR"
},
"name": "Angleterre"
}
=> Will create country with one localized value
same as POST, you must specified @language or put all localized data
PUT http://api.example.com/countries/1
{
"@context" : {
"@language": "it"
},
"name": "Inghilterra"
}
=> Will add or replace locale "it" name for the resource /countries/1
PUT http://api.example.com/countries/1
{
"name": {
"fr" : "Angleterre"
}
}
=> Will delete all localization for name and just have fr localization
add a specific endpoint to api like :
GET http://api.example.com/countries/1/locales
{
"@context": "http://schema.org",
"@id": "/http://api.example.com/countries/1/locales",
"@type": "hydra:PagedCollection",
"hydra:totalItems": 2,
"hydra:itemsPerPage": 3,
"hydra:firstPage": "/countries",
"hydra:lastPage": "/countries",
"hydra:member": [
{
"@type": "Locale",
"@id": "/locale/fr"
},
{
"@type": "Locale",
"@id": "/locale/en"
}
]
}
=> Will return all available locale for the resource
Actually IriConverter use only a field name 'id' for entity identifier.
It's an issue, the good solution is to read class metadata from doctrine and use the field maked with @Orm\Id annotation
The current filters on collections allow to search for entities matching a given criteria. But sometimes we don't want to find entities, but the first entity matching a criteria. The easiest way to achieve that would be to add an endpoint /offers/findOne?criteria
. So basically an endpoint on which the filters enabled for the collection are enabled too, but which returns the first entity found, pretty much like we did /offers?criteria
and then retrieved hydra:member[0]
.
Do you think this could be added or do you deem it too specific?
Because of this line if the resource already has one operation (in my example the custom one added), it won't add the default GET
, PUT
, DELETE
operations.
I know this is a nice behavior when it comes to add only the resources you want (like no POST
in the collection from the readme) but when adding one resources it's bringing extra lines of code to get back the normal behavior.
What about adding a parameter inside the resource that is beeing checked by the DI compilation to avoid loosing default routes?
P.S.: Sorry for beeing a lazy guy \o/
Hello,
When I made โโa PUT request on my user id identified with FOS Oauth SERVER BUNDLE and FOS USER , I am instead a POST because it does not retrieve the user object.
If I want to update the User object different from mine , no problem
Here the User with id 3 with the token that begins with MWQ1 ....
PUT on api/v1/users/ 2 it's work
PUT on api/v1/users/ 3 not work
Here the User with id 2 with the token that begins with NTU1 ....
PUT on api/v1/users/3 it's work
PUT on api/v1/users/2 not work
In Dunglas\ApiBundle\FosUser\EventSubscriber.php
public function updateObject(ObjectEvent $event) { $object = $event->getObject(); if ($object instanceof UserInterface) { $this->userManager->updateUser($object); $this->eventDispatcher->dispatch(Events::POST_UPDATE, $event); $event->stopPropagation(); } }
$object is null for the user who wants to change their own user object but correct for the user object of another user..
I do not know if I explained the problem ...
Blump
We need to create different (de)normalizers to handle complex or specific types such as collection or DateTime
.
Using the built-in Symfony Serializer system.
I know this is in a heavy development state but I'd be nice to have a changelog instead of reading the commits :).
When using dates, we rarely need filter a collection which has the given date but rather filter by period: before or after a date or between two dates.
Taking into account the change in the way we expose URL as mentioned in the PR #43, we could use the following syntax:
url?filter[date][propertyName][after]=value
url?filter[date][propertyName][after]=value
Where value
is a format understandable for the instantiate a \DateTime
from it.
Sometimes you don't want to look for a specific date but just want to give a year:
url?filter[date][createdAt][after]=2005&filter[date][updatedAt][before]=2015
Will filter the collection to expose only the items with a createdAt
date superior or equal to 2006-01-01
and a updatedAt
date value inferior or equal to 2014-12-32
.
If we do so maybe adding a support for the month would make sense too.
Edit: Adding a support for the month would be logical if we add one for the year, but IMO it would be too much and lead to confusion regarding the format and the use case is specific/rare enough to let the one to add his own filter.
When I have a relation, I can't specify the ID of the new group in the sandbox of NelmioAPIDocBundle:
When I try to put ["@id":"/~felicitus/DunglasApiBundleDemo/web/app_dev.php/api/groups/1"]
into the groups field, the resulting JSON is:
groups: "["@id":"/~felicitus/DunglasApiBundleDemo/web/app_dev.php/api/groups/1"]"
when it should be:
groups: ["@id":"/~felicitus/DunglasApiBundleDemo/web/app_dev.php/api/groups/1"]
I have no idea if the issue is caused by DunglasAPIBundle or NelmioAPIDocBundle. The best would be for NelmioAPIDocBundle to recognize that we expect an array here, and support adding array elements to there.
Additionally, this bundle returns an internal server error when attempting to post the quoted groups parameter:
{
"@context": "/~felicitus/DunglasApiBundleDemo/web/app_dev.php/api/contexts/Error",
"@type": "Error",
"hydra:title": "An error occurred",
"hydra:description": "Warning: Invalid argument supplied for foreach()",
"trace": [
{
"file": "/home/felicitus/repos/DunglasApiBundleDemo/vendor/dunglas/api-bundle/JsonLd/Serializer/ItemNormalizer.php",
"line": 247,
"function": "handleError",
"class": "Symfony\\Component\\Debug\\ErrorHandler",
"type": "->",
"args": [
2,
"Invalid argument supplied for foreach()",
"/home/felicitus/repos/DunglasApiBundleDemo/vendor/dunglas/api-bundle/JsonLd/Serializer/ItemNormalizer.php",
247,
{
"data": {
"_format": "json",
"name": "dsfsadf",
"groups": "[\"@id\":\"/~felicitus/DunglasApiBundleDemo/web/app_dev.php/api/groups/1\"]"
},
"class": "AppBundle\\Entity\\Group",
"format": "json-ld",
"context": {
"0": {
"groups": [
"user"
]
},
"resource": {}
},
(skipped rest of the backtrace)
}
As existing filters are based on properties, when using a name converter, it feels odd to have properties and filters named differently.
That's why I'd like to use the name converter for filters too.
The straightforward solution is to inject the name converter, if configured, in each filters (I think we won't inject it in the AbstractFilter, as custom filters might no be based on a property, therefore, might not need conversion).
Injecting the converter is what we are already doing in ItemNormalizer for instance.
But, another solution came to my mind:
convertedName
(or any better name) property in AttributeMetadata
AttributeLoader
and populate the new property with the converted name using the converter.ClassMetadataFactory
in AbstractFilter and provide a getMappingMetadata
method.The drawback is that we need to maintain both mappingMetadata
from ClassMetadataFactory
and doctrine metadata in the current filters. In such cases, we need to loop over the mappingMetadata
to find the matching doctrine property and the proper convertedName.
The benefits are that we won't need to inject the name converter anymore, as the api.mapping.class_metadata_factory
is used instead.
For what it is worth, the conversion is also done only once. Custom filters are free to use metadata or not.
Do you see anything wrong with this approach ? Do you have any suggestion ?
The link in the TOC for returning a page collection is broken (I guess it's the R
of Request
which broke the link, should be `r' instead).
Pass $context
is subsequent calls to normalize()
.
Hello,
I have this error, do you have an idea?
CRITICAL - Fatal Parse Error: syntax error, unexpected 'finally' (T_STRING), expecting catch (T_CATCH)
CRITICAL - Uncaught PHP Exception Symfony\Component\Debug\Exception\FatalErrorException: "Parse Error: syntax error, unexpected 'finally' (T_STRING), expecting catch (T_CATCH)" at /vendor/dunglas/api-bundle/Routing/Router.php line 75
Thanks!
At the moment only the filter description (hydra:search
) of the search filter is well implemented. For the order filter and date filter the description is lacking or invalid.
It would be nice to add api versioning with a customizable prefix /api/1/
or /myapi/v1/
.
Thoughts?
As explaiend here, given we have a relation between User
and Job
, it is possible to display the properties of Job
when getting the properties of User
, which gives the following result:
{
"@context": "/api/contexts/User",
"@id": "/api/users/1",
"@type": "User",
"username": "John Doe",
"email": "[email protected]",
"roles": [
"ROLE_USER"
],
"jobs": [
{
"@id": "/api/jobs/101",
"@type": "Job",
"title": "President",
"abbreviation": "PR",
"mandate": "/api/mandates/12"
}
]
}
Now as you can see with the JSON above, I also have a relation between Job
and Mandate
. If I use the same pattern (adding a serialization group to Mandate
, I get the following result:
{
"@context": "/api/contexts/User",
"@id": "/api/users/1",
"@type": "User",
"username": "John Doe",
"email": "[email protected]",
"roles": [
"ROLE_USER"
],
"jobs": [
{
"@id": "/api/jobs/101",
"@type": "Job",
"title": "President",
"abbreviation": "PR",
"mandate": {
"@id": "/api/mandates/12",
"@type": "Mandate",
"startAt": "2016-03-14T20:34:19+01:00",
"endAt": "2016-08-03T10:53:22+02:00",
"jobs": [
"/api/jobs/32",
"/api/jobs/96",
"/api/jobs/99",
"/api/jobs/100",
"/api/jobs/101"
]
}
}
]
}
Regardless on which attribute I putted the serialization group (for ex: in this case I added it on startAt
.
In other words, the serialization group does work for this case but completly ignore which attributes we wish to expose for the embed relation of the embed relation.
The following syntax is considered as a malformed YAML:
# app/config/services.yml
services:
resource.offer.search_filter:
parent: "api.doctrine.orm.search_filter"
arguments: [ {
"id": "exact", # Filters on the id property, allow both numeric values and IRIs
"price": "exact", # Extracts all collection elements with the exact given price
"name": "partial" # Elements with given text in their name
} ]
In Adding Doctrine ORM fitlers.
A valid one would be:
# app/config/services.yml
services:
resource.offer.search_filter:
parent: "api.doctrine.orm.search_filter"
arguments: [ { id: "exact", price: "exact", name: "partial" } ]
And for very long ones or when we wished to put some comments:
# app/config/services.yml
services:
resource.offer.search_filter:
parent: "api.doctrine.orm.search_filter"
arguments:
-
id: "exact" # Filters on the id property, allow both numeric values and IRIs
price: "exact" # Extracts all collection elements with the exact given price
name: "partial" # Elements with given text in their name
As of now it is possible to customize the number of items per page at a global level on the API side with the option items_per_page
.
But the number of items per page is a parameter you may wish to change for some entities on the API side and sometimes let the client adjust it to his need.
To cover most of the use case without having to override a DataProvider a defining a custom Paginator, tit should be possible to configure the following with some parameters in the config:
items_per_page
on a global basis on the API side (already possible)items_per_page
on a resource basis on the API sideKeep it as it is.
services:
resource.dummy:
parent: "api.resource"
arguments: [ "AppBundle\Entity\Dummy" ]
calls:
- method: "setPagination"
arguments: 50
And in this case, regardless of the value of items_per_page
in the config.yml
, this pagination for Dummy
will be at 50
.
Since it's for all the resources it seem logical to define it in the config.yml
:
dunglas_api:
title: "Your API name"
description: "The full description of your API"
default:
items_per_page:
default_value: 30
client_pagination: true # Default to false
order: ~
Maybe adding which values we allow for the pagination via a request would be nice too. If you deem it too specific then letting the user extending the paginator to achieve that is fine.
services:
resource.dummy:
parent: "api.resource"
arguments: [ "AppBundle\Entity\Dummy" ]
calls:
- method: "enableClientPagination"
arguments: [10, 50, 100, 200] # valid values, if no value provided all value is accepted.
Syntax proposal for the custom pagination on the client side:
url?itemsPerPage=value
As the core of the bundle is now independent of JSON-LD and Hydra (it's possible to add HAL or any other serialization format support), what do you think about renaming the bundle "ApiBundle"?
I believe there is some issues with the current doc of disabling operations:
calls
key:resource.product:
parent: "api.resource"
arguments: [ "AppBundle\Entity\Product" ]
calls: # is missing
- [ "initCollectionOperations", [ [ "@resource.product.collection_operation.get" ] ] ]
tags: [ { name: "api.resource" } ]
@resource.product
service is registered in @resource.product.collection_operation.get
and vice-versa it causes a circular reference.I have an entity which has a ManyToMany relation to another entity:
/**
* This object represents an unit. Units can be: Volt, Hertz etc.
*
* @ORM\Entity
* @TargetService(uri="/unit")
* @ExclusionPolicy("none")
**/
class Unit extends BaseEntity {
/**
* The name of the unit (e.g. Volts, Ampere, Farad, Metres)
* @ORM\Column(type="string")
* @Type("string")
*
* @var string
*/
private $name;
/**
* The symbol of the unit (e.g. V, A, F, m)
* @ORM\Column(type="string")
* @Type("string")
* @var string
*/
private $symbol;
/**
* Defines the allowed SiPrefixes for this parameter unit
* @ORM\ManyToMany(targetEntity="PartKeepr\SiPrefixBundle\Entity\SiPrefix")
* @ORM\JoinTable(name="UnitSiPrefixes",
* joinColumns={@ORM\JoinColumn(name="unit_id", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="siprefix_id", referencedColumnName="id")}
* )
* @Type("ArrayCollection<PartKeepr\SiPrefixBundle\Entity\SiPrefix>")
* @var ArrayCollection
*/
private $prefixes;
However, the generated doc using NelmioAPIDocBundle doesn't include that relation as input:
I'm not sure if this is an issue of the NelmioAPIDocBundle or this bundle and if this is supported at all.
Although the FOSUserBundle integration is pretty simple, there is no mention of it in the doc. Could it be added?
As of now, if we filter a collection on a not enabled property, the collection will be returned as a whole as if no filter is given. bIMO it is error prone in a sense that you have no way to tell there is an error occurred unless you take a look at the result.
Would it be possible to change that or it's a desired behavior?
Given an entity with has a relation with itself, for instance via the attributes parent
and children
, the circular reference is not handled.
I'm not sure if it should be handled natively or not, but if not then I guess we should use a custom normalizer to handle it. In this case there is three problems:
@api.json_ld.normalizer.item
requires lots of arguments. While I'm not really against it, since if we require multiple normalizer for such use case, we can declare an abstract one to lighten the declaration. If you prefer that rather than declaring the abstract normalizer in your bundle, I believe this could be added in the doc.In both cases it may be a use case frequent enough to deserve a chapter in the doc. What do you think?
cc/ @Pyrex-FWI
One request often made when filtering a collection by values is the case of the null
value. Sadly this is a very painful case because the value retrieved on the server side is always a string and that it's no possible with the current implementation to pass an empty value.
Unfortunately I didn't find much on the subject aside from this post which suggest a "hacky" solution: defining custom values.
I tested a little bit with a StrongLoop application and the following query ?filter[where][property]=null
works whatever the type of the value is.
The only problem is for string values. Indeed it becomes impossible to search for a string with the value "null"
.
@dunglas, @sroze what are your though on this case? Should we do as StrongLoop which has the drawback of disabling the search filter for string properties of value "null"
?
I'm using the FOSUserBundle with my User
entity. I wish to hide some properties of the User
entity, for example the password
and the plainPassword
. However, I still need to be able to use the plainPassword
property in the PUT
or POST
to set or update the password of the user.
Here's the configuration:
<?php
// src/AppBundle/Entity/User.php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use FOS\UserBundle\Entity\User as FosUser;
use Symfony\Component\Serializer\Annotation\Groups;
/**
* User.
*
* @ORM\Entity
*/
class User extends FosUser
{
/**
* @var int
*
* @ORM\Column(type = "integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy = "AUTO")
* @Groups({"user"})
*/
protected $id;
/**
* @var string
*
* @Groups({"user"})
*/
protected $email;
/**
* @var string
*
* @ORM\Column(type = "string", length = 45)
* @Groups({"user"})
*/
private $username;
/**
* @var string
*
* @Groups({"password"})
*/
protected $plainPassword;
public function __construct()
{
parent::__construct();
}
}
# app/config/services.yml
resource.user:
parent: api.resource
arguments: [ AppBundle\Entity\User ]
calls:
- [ initNormalizationContext, [ { groups: [ user ] } ] ]
- [ initDenormalizationContext, [ { groups: [ password, user ] } ] ]
tags: [ { name: api.resource } ]
When I GET
an entity or a collection, the properties are hidden as expected. However the POST
fails stating the column password
cannot be null.
Have you any idea on what may be the problem?
More like guidelines for custom filters:
setParameters
instead of setParameter
as it will wipe out all previous parametersI do not know if it has really its place here though.
The sample doesn't work.
In ResourcePass.php => all tagged element with "api.resource" are added to resource_collection (OK :) )
But method call "addItemOperation" and "addCollectionOperation" are added on custom resource wich not implements these method (ResourceInterface not required them)
So, maybe add a check that the new resource implements default resource ?
Or maybe add options to yml to filter default operation (for having a more simple definition) like :
resource.locale:
class: "MyBundle\MyCustomResource"
buildItemOperations: ["GET"]
buildItemCollectionOperations : ["GET", "POST"]
tags: [ { name: "api.resource" } ]
what do you think ?
Hello,
Sorry for my english, I'm French ....
After configuring and FOS FOS BUNDLE USER AUTH USER. I have no problem with but with a GET on HOST POST / api / books for example , I have this error:
hydra:description": "Catchable Fatal Error: Argument 1 passed to Dunglas\\ApiBundle\\FosUser\\EventSubscriber::__construct() must implement interface Symfony\\Component\\EventDispatcher\\EventDispatcherInterface, none given, called in /var/www/local.dev/XXXX/api-platform/app/cache/prod/appProdProjectContainer.php on line 331 and defined"
thank you for your answers
Overriding a method of the controller is easy as it's just requires to extend the ResourceController
. However in the case we wish to add a new action to the controller, for example countAction
, to get the API endpoint GET /collection/count
; It would be possible to add our route manually in our routing file, but then our rout would not "inherit" the prefixes that it would get if it were declared directly in the parent controller ResourceController
. Is there a way to that in a more elegant manner?
The goal is to release a 0.1.0 version when Symfony 2.7 will be out.
What do you think @sroze?
Should be done in Nelmio directly.
The documentation is becoming quite long so a TOC would be very much appreciated regardeless if the doc is planned to be move elsewhere later!
I have started developing a demo app for DunglasApiBundle. I tried to deserialize a new User with a new Group:
POST api/users
{"_format": "json",
"groups": [{
"name":"newgroup"
}],
"name": "test12311"
}
I have configured serialization groups, however, I'm receiving the following error:
hydra:title: "An error occurred"
hydra:description: "Nested objects for attribute "groups" of "AppBundle\Entity\User" are not enabled. Use serialization groups to change that behavior."
Here's my entity: https://github.com/felicitus/DunglasApiBundleDemo/blob/master/src/AppBundle/Entity/User.php
Throw a circular reference error in some cases.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.