Skip to content

Allow plain IDs with allow_plain_identifiers#1365

Merged
soyuka merged 1 commit into
api-platform:masterfrom
soyuka:fix/api-platform/249
Oct 13, 2017
Merged

Allow plain IDs with allow_plain_identifiers#1365
soyuka merged 1 commit into
api-platform:masterfrom
soyuka:fix/api-platform/249

Conversation

@soyuka

@soyuka soyuka commented Sep 12, 2017

Copy link
Copy Markdown
Member
Q A
Bug fix? yes/no (depends on the POV)
New feature? yes/no (same)
BC breaks? no
Deprecations? no
Tests pass? yes
Fixed tickets api-platform/api-platform#249 #1363
License MIT
Doc PR n/a

@soyuka soyuka force-pushed the fix/api-platform/249 branch from e7218e0 to 6f862a7 Compare September 12, 2017 14:09
}

if (!is_array($value)) {
// repeat the code so that IRIs keep working with the json format

@soyuka soyuka Sep 12, 2017

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to test that Content-Type is application/json here, not sure if it's possible or wanted...

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you can just check the $format var.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

not really, json is the format for hal, jsonld and json no?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, it's jsonld for JSON-LD and jsonhal for HAL.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, my bad dunno why I thought so...

@soyuka soyuka force-pushed the fix/api-platform/249 branch 6 times, most recently from 3f4a223 to 0cbf4dd Compare September 18, 2017 18:11
@soyuka soyuka changed the base branch from master to 2.1 September 18, 2017 18:11
@soyuka soyuka force-pushed the fix/api-platform/249 branch from 0cbf4dd to 5e8619f Compare September 18, 2017 18:14

if (!is_array($value)) {
// repeat the code so that IRIs keep working with the json format
if ('json' === $format && $this->itemDataProvider) {

@dunglas dunglas Sep 19, 2017

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get the idea and the use case, but it hurts me a bit:

  • it doesn't fit the hypermedia philosophie of API Platform
  • it doesn't work consistently across formats (XML or CSV for instance may need this feature as well)

May I suggest an alternative implementation:

  • add a new flag allow_plain_identifiers defaulting to false
  • if this flag is on, execute your code in all circonstances, regardless of the format

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And then it will be merged in master.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You see :p had the same concerns ^^

@soyuka soyuka changed the base branch from 2.1 to master September 19, 2017 07:52
@soyuka soyuka force-pushed the fix/api-platform/249 branch 2 times, most recently from 43017af to 6a11dd7 Compare September 19, 2017 08:09
@soyuka soyuka changed the title Allow plain IDs when the format is "json" Allow plain IDs with allow_plain_identifiers Sep 19, 2017
@teohhanhui

Copy link
Copy Markdown
Contributor

I don't think we need a config option. @id in plain JSON (both normalization and denormalization) is a bug. For BC, we should keep it but trigger a deprecation error.

@soyuka

soyuka commented Sep 19, 2017

Copy link
Copy Markdown
Member Author

To you we should:

  1. enable @id only for json-ld
  2. enable id only for json, xml, csv

@dunglas wdyt? I'm also to remove @id support in other formats.

@teohhanhui

Copy link
Copy Markdown
Contributor

There is no question that @id is defined in the JSON-LD spec. For all of the plain (non-hypermedia) formats (JSON, XML, etc.), there is not really a right or wrong thing to do, but using the item's ID properties seems appropriate.

@soyuka

soyuka commented Sep 19, 2017

Copy link
Copy Markdown
Member Author

Agreed @teohhanhui, though IRIs are such great at identifying things that it'd be a shame not to be able to use them for other things (might be a point to keep them with other formats).

@soyuka

soyuka commented Sep 19, 2017

Copy link
Copy Markdown
Member Author

For now I can go back to my previous commit to do:

if ('jsonld' !== $format && $this->itemDataProvider) {
 //use id 
}

@dunglas

dunglas commented Sep 19, 2017

Copy link
Copy Markdown
Member

I don't agree:

  • We already decided to use IRIs as identifiers everywhere. I'm ok to add an option to change this behavior in write mode (= support both plain IDs and IRIs), but not to remove support of IRIs in other formats than JSON-LD and HAL.
  • In JSON-LD (and HAL), we should give the possibility to access to both the raw id property and to the @id IRI. It's mandatory to support client-side generated UUIDs for instance.

@soyuka

soyuka commented Sep 19, 2017

Copy link
Copy Markdown
Member Author

In that case @dunglas feel free to merge! I see no issues in keeping @id and id :)

protected $allowPlainIdentifiers;

public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, IriConverterInterface $iriConverter, ResourceClassResolverInterface $resourceClassResolver, PropertyAccessorInterface $propertyAccessor = null, NameConverterInterface $nameConverter = null, ClassMetadataFactoryInterface $classMetadataFactory = null)
public function __construct(PropertyNameCollectionFactoryInterface $propertyNameCollectionFactory, PropertyMetadataFactoryInterface $propertyMetadataFactory, IriConverterInterface $iriConverter, ResourceClassResolverInterface $resourceClassResolver, PropertyAccessorInterface $propertyAccessor = null, NameConverterInterface $nameConverter = null, ClassMetadataFactoryInterface $classMetadataFactory = null, ItemDataProviderInterface $itemDataProvider = null, $allowPlainIdentifiers = false)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

bool $allowPlainIdentifiers = false

@soyuka soyuka force-pushed the fix/api-platform/249 branch from 6a11dd7 to 965ff42 Compare September 19, 2017 12:59
@meyerbaptiste

Copy link
Copy Markdown
Member

Should we use IRIs as identifiers with JSON API too?

@soyuka soyuka force-pushed the fix/api-platform/249 branch from 965ff42 to b28d524 Compare September 21, 2017 11:47
@Simperfit

Copy link
Copy Markdown
Contributor

@dunglas could you re-review it ? @soyuka could you rebase ?

@soyuka soyuka force-pushed the fix/api-platform/249 branch from b28d524 to 44b6fab Compare October 10, 2017 08:14
@soyuka

soyuka commented Oct 10, 2017

Copy link
Copy Markdown
Member Author

rebased

@sroze

sroze commented Oct 10, 2017

Copy link
Copy Markdown
Contributor

I really don't think this is a great choice to do so. What's the point? It's just adding another way to do something already possible... If you look at #1363 it's just because "I don't want to use this code" or in api-platform/api-platform#249 the reason is "I think plain IDs will be used for many years to come".

We are convinced that semantic web is the way to go. The way to properly go towards to this direction is to have people using IRIs as their identifiers... let's educate for this instead of allow "plain IDs" :(

@soyuka

soyuka commented Oct 10, 2017

Copy link
Copy Markdown
Member Author

@sroze totally agree when it comes to formats like json-ld. Though with standard json, to me, accepting an id (not an IRI) should be valid.

@glnemeth

Copy link
Copy Markdown

@sroze This is needed for example in our project, where we are currently using JSON (not LD-JSON), so having IRIs is not required and forcing IRIs on our developers is unneccessary and adds to the work. Also our routing is not fixed as the project is still evolving, so it's easier to send IDs, instead of constantly following the changes of routing on frontend and backend too.


if (!is_array($value)) {
// repeat the code so that IRIs keep working with the json format
if (true === $this->allowPlainIdentifiers && $this->itemDataProvider) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is $this->itemDataProvider === null and true === $this->allowPlainIdentifiers ? Instead of silently not doing anything, should we throw an exception instead?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could, maybe a bit overkill, this dependency should be a hard dep, it's just nullable to avoid breaking.

@sroze

sroze commented Oct 10, 2017

Copy link
Copy Markdown
Contributor

Also our routing is not fixed as the project is still evolving, so it's easier to send IDs, instead of constantly following the changes of routing on frontend and backend too.

That's an interesting argument because that's actually where using IRIs should help you :)

But fair point for the JSON format. If it helps... 👍 then...

@soyuka soyuka force-pushed the fix/api-platform/249 branch from 44b6fab to ac4622c Compare October 12, 2017 06:23
@soyuka soyuka force-pushed the fix/api-platform/249 branch from ac4622c to 808b5d3 Compare October 13, 2017 08:14
@soyuka soyuka merged commit 318d3b3 into api-platform:master Oct 13, 2017
@soyuka soyuka deleted the fix/api-platform/249 branch October 13, 2017 09:31
@iciantoine

Copy link
Copy Markdown

Hello guys. Is it possible to merge this in 2.1 branch? I think this is a really important feature and I hope to see it in stable version ASAP. Thanks!

@dunglas

dunglas commented Nov 7, 2017

Copy link
Copy Markdown
Member

Sorry we respect semver and new features are always merged in minor releases. Patch releases only contain bug and security fixes.

@julienpillias

Copy link
Copy Markdown

According to this PR, I should be able to update (PUT) nested document with plain id ?
Just tried, a, dstille have this error :

Nested documents for attribute "groups" are not allowed. Use IRIs instead
{
  "id":1,
  "name": "foo",
  "groups": [
       {
           "id":1,
           "name": "bar"
       }
   ]
}

Composer.json :

"api-platform/core": "2.2.x-dev"

(composer update done)

config.sjon

api_platform:
    allow_plain_identifiers: true

Forget something ? Yet not ready maybe ?

@soyuka

soyuka commented Nov 9, 2017

Copy link
Copy Markdown
Member Author

@julienpillias you have a serialization issue fix your groups and this will indeed work.

@julienpillias

julienpillias commented Nov 9, 2017

Copy link
Copy Markdown

OK, had to put denormalization_context into the nested document too. TY for the tips
But now, having this error :

No route matches "/app_dev.php/groups/1"

This route exists, but should be http://api.xxxxx.project.local/app_dev.php/groups/1, because of my routing I think :

api:
    resource: '.'
    type:     'api_platform'
    host:     'api.{project_name}'
    defaults:
        project_name: xxxx.project.local
    requirements:
        project_name: xxxx.project.local|xxxx.fr|preprod.xxxx.fr

I don't see any option in apiPlatform to specify a route parameter. At least, is it possible to use the default parameter ?

@julienpillias

julienpillias commented Nov 9, 2017

Copy link
Copy Markdown

So just dig into the code, and found this in https://github.com/api-platform/core/blob/master/src/Bridge/Symfony/Routing/IriConverter.php (Line 141) :

public function getSubresourceIriFromResourceClass(string $resourceClass, array $context, int $referenceType = UrlGeneratorInterface::ABS_PATH): string

Change it to

public function getSubresourceIriFromResourceClass(string $resourceClass, array $context, int $referenceType = UrlGeneratorInterface::ABS_URL): string

(ABS_PATH => ABS_URL).
No more problem !
I do not know if this could have some side effect !
Should we use ABS_URL every where in iriConverter to avoid problem like mine ?

EDIT : maybe still having the problem.... digging in

@soyuka

soyuka commented Nov 9, 2017

Copy link
Copy Markdown
Member Author

(ABS_PATH => ABS_URL).

this should be configurable I think but it is not actually :|.

@julienpillias

Copy link
Copy Markdown

could try a PR for this.

Something in config.json ?
config.json

api_platform:
    use_absolute_url: true # default will be false

@soyuka

soyuka commented Nov 9, 2017

Copy link
Copy Markdown
Member Author

Not sure, I think that this is a configuration issue on your side but I have no idea what (something linked to symfony routing configuration) :|.

@julienpillias

Copy link
Copy Markdown

On my project, I have a "classic" web site (SF + twig), using mysite.com (or www.mysite.com) AND have the API on api.mysite.com for mobile application for example.

So if apiPlatform check route /entity/id, it would not be an API ressource. It's why I need ABS_URL their, so ressource will be found with http://api.mysite.com/entity/id

Don't think I have a routing problem here, i've checked router:debug, and do not have any problem with api doc, or my "classic" web site".

@soyuka

soyuka commented Nov 10, 2017

Copy link
Copy Markdown
Member Author

Can you open an issue about this with all the details? Thanks.

@julienpillias

Copy link
Copy Markdown

Already done few week's ago :)
api-platform/api-platform#427

hoangnd25 pushed a commit to hoangnd25/core that referenced this pull request Feb 23, 2018
Allow plain IDs with `allow_plain_identifiers`
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants