Problem/Motivation

In order to allow overriding the prefix of the API successfully in JSON API Extras and other extending modules.

Proposed resolution

We need to stop hard-coding /jsonapi/. Instead, we want to have a getPathPrefix() that contains this information.

Remaining tasks

Do it.

User interface changes

None.

API changes

Introduce getPathPrefix() in the ResourceTypeRepository.

Data model changes

None.

Comments

e0ipso created an issue. See original summary.

e0ipso’s picture

Title: Make ResourceTypeRepository aware of the route prefix » Make ResourceTypeRepository aware of the path prefix
Issue summary: View changes
e0ipso’s picture

StatusFileSize
new2.65 KB

This is a simple one.

e0ipso’s picture

Status: Active » Needs review
e0ipso’s picture

Status: Needs review » Needs work

The last submitted patch, 3: 2949632--path-prefix--3.patch, failed testing. View results

e0ipso’s picture

Status: Needs work » Needs review
StatusFileSize
new801 bytes
new3.44 KB

Add mock.

e0ipso’s picture

Status: Needs review » Fixed

I'm going to merge this. Please leave any comments you want, I'll address them as follow ups.

  • e0ipso committed d5581d8 on 8.x-1.x
    Issue #2949632 by e0ipso: Make ResourceTypeRepository aware of the path...
e0ipso’s picture

Status: Fixed » Needs review
StatusFileSize
new651 bytes

This was missing.

  • e0ipso committed 1f4398b on 8.x-1.x
    Issue #2949632 by e0ipso: Make ResourceTypeRepository aware of the path...
e0ipso’s picture

Status: Needs review » Fixed

🎊

gabesullice’s picture

Hm, I don't like this one (yet). There's something cool about letting a resource type repository define an entire API surface, but it makes me worry about people (mis)using this internal "feature".

e0ipso’s picture

We were incorrectly hard coding the resource URL in the Entity to JSON API service. This successfully abstracts that. On top of that this allows a massive simplification of JSON API Extras routing. Additionally, I think it's semantically correct that the repository has an access route defined to it (the entry point).

Does this change your concerns about misunderstanding the internal API?

wim leers’s picture

I am also concerned. If a resource type can provide a path prefix, that implies that five different resource types can have five different path prefixes. I doubt that that is what we want?

If you agree with that, then the only possible conclusion is that this is the wrong place for this abstraction to live.

wim leers’s picture

Perhaps you're wondering where I then do think that this abstraction should live? I think making this a container parameter would be one viable approach: there can then only ever be one value, and it can be injected into any service that needs it. The jsonapi_extras module could then override it.

Also: #2878463: [PP-1] Define a JSON API link relation for entities is related.

gabesullice’s picture

We were incorrectly hard coding the resource URL in the Entity to JSON API service. This successfully abstracts that. On top of that this allows a massive simplification of JSON API Extras routing.

Yes, it's clearly an improvement in both cases :). I agree that it should be set differently than the status quo. I think my remaining concern is merely that I'm not yet convinced the repository is the best choice among the various alternatives.

I think it's semantically correct that the repository has an access route defined to it (the entry point).

This is the only piece of the change where I think I need more explanation/convincing/understanding.

+++ b/src/Routing/Routes.php
@@ -80,7 +80,8 @@ class Routes implements ContainerInjectionInterface {
+    $path_prefix = $this->resourceTypeRepository->getPathPrefix();

@Wim Leers, I think you're still partly suffering from the same initial misunderstanding I had. Note that it's the repository that defines the prefix, not each individual resource type.

That's slightly less concerning I think. I'm interested in the container idea, but I would need to know more about how that works to have a solid opinion.

wim leers’s picture

I think you're still partly suffering from the same initial misunderstanding I had.

I don't think so. See https://cgit.drupalcode.org/jsonapi/commit/?id=4b5b103 — which was done in #2949635: Make the resource type aware of the resource path. (I don't know why it wasn't done as part of this issue, since it's semantically closely related.)

wim leers’s picture

Status: Fixed » Needs review
StatusFileSize
new3.26 KB

D'oh, I should learn to read: https://cgit.drupalcode.org/jsonapi/commit/?id=4b5b103 added ResourceType::getPath(), which excludes the path prefix. This is extremely confusing though, because usually "path" in the context of the web means "the path component of a URI", but here it means "the _last_part_ of the path component of a URI". (Which is related to the concern you raised at #2949635-7: Make the resource type aware of the resource path.)

I think we can make this all quite a bit clearer. Proposal in patch.

wim leers’s picture

StatusFileSize
new4.51 KB
new4.72 KB

Or, if you prefer, \Drupal\jsonapi\ResourceType\ResourceTypeRepositoryInterface::getPrefixPathSegment() and \Drupal\jsonapi\ResourceType\ResourceType::getPathSegments(). That would match the terminology in https://tools.ietf.org/html/rfc3986#section-3.3.

Status: Needs review » Needs work

The last submitted patch, 20: 2946932-20.patch, failed testing. View results

wim leers’s picture

Status: Needs work » Needs review
StatusFileSize
new1.61 KB
new5.76 KB

Fix for #20.

gabesullice’s picture

Status: Needs review » Reviewed & tested by the community
+++ b/src/ResourceType/ResourceType.php
@@ -244,13 +244,15 @@ class ResourceType {
-    return sprintf('%s/%s', $this->getEntityTypeId(), $this->getBundle());
+    return sprintf('/%s/%s', $this->getEntityTypeId(), $this->getBundle());

+++ b/src/ResourceType/ResourceTypeRepository.php
@@ -77,7 +77,7 @@ class ResourceTypeRepository implements ResourceTypeRepositoryInterface {
-    return 'jsonapi';
+    return '/jsonapi';

These changes address my only nit.

I'm assuming that because @Wim Leers added these patches, he is no longer in favor doing something with the container. Therefore, RTBC!

wim leers’s picture

The container thing could still happen in the future, if we deem that better. This will do for now.

e0ipso’s picture

I don't feel strongly either way, but I thought to clarify this.

This is extremely confusing though, because usually "path" in the context of the web means "the path component of a URI"

In the context of REST the resource type path is the path (after the API's entry point) that gives access to that resource type for the usual CRUD operations. So I think that ResourceType::getPath could not be clearer. I'm not aware of any significance of segment in REST. For the prefix… I don't know any specific term for the path of the entry point of the API, hence I went with getPathPrefix but I could've gone with getEntryPointUri.

As I said, this is extremely irrelevant and I don't feel strongly either way, but changing this will break JSON API Extras.

Feel free to merge if you feel strongly about this.

wim leers’s picture

Status: Reviewed & tested by the community » Needs review

Thanks for #25, that helps, and makes a ton of sense! 👍

I think ResourceType::getPath() plus ResourceTypeRepository::getBasePath() would then probably be the best method name.

wim leers’s picture

StatusFileSize
new5.38 KB

Implemented #26 based on #25. That also means fewer changes :)

gabesullice’s picture

Status: Needs review » Reviewed & tested by the community

LGTM.

wim leers’s picture

Assigned: Unassigned » e0ipso

I'd love to commit this, but I know this will impact jsonapi_extras. So I want to coordinate with @e0ipso to commit + release this simultaneously with jsonapi_extras.

wim leers’s picture

e0ipso’s picture

This will break several integrations that rely on the old method name and output. Are these changes worth all the hassle in your opinion?

If you want to still move forward with this I'll need to coordinate releases for Contenta CMS, ContentaJS and JSON API Extras. So I will need some preparation before we can tag a release with this one.

wim leers’s picture

I'd be fine doing this only in 2.x — I think that would help? :)

wim leers’s picture

Are these changes worth all the hassle in your opinion?

Also, yes, I think this is worth the hassle. Especially if this goes into core.

Currently a string is returned, not a path prefix. And "path prefix" is really "base path" everywhere else in the web world (and in Drupal).

Furthermore, your commit here back in March actually breaks jsonapi_extras in situations where it chooses to override this base path/path prefix! That's why #2971745: Don't hardcode `/jsonapi/` in FormatSetter, read JSON API base path from container parameter instead exists. And it's blocked on this issue.

Finally: I wish you'd waited for feedback rather than just committed this back in March. 😞 Both Gabe and I responded quickly after the fact, but you let our responses linger :( If you'd have responded faster, or asked for feedback, we could've prevented the need for new releases of all those projects. I understand you just wanted to get things done, but if you want contributors to contribute, it's better to build consensus before committing. Let's do better from now on? :)

e0ipso’s picture

Status: Reviewed & tested by the community » Needs review
StatusFileSize
new4.35 KB

Merge conflicts.

e0ipso’s picture

Finally: I wish you'd waited for feedback rather than just committed this back in March. 😞 Both Gabe and I responded quickly after the fact, but you let our responses linger :( If you'd have responded faster, or asked for feedback, we could've prevented the need for new releases of all those projects. I understand you just wanted to get things done, but if you want contributors to contribute, it's better to build consensus before committing. Let's do better from now on? :)

I'm sorry you are frustrated by this. I think that this has faded in importance, but still worth addressing.

I think this is due to the different nature of our involvement on the project. I want to get things done right there and then because it's my only window of contribution. I don't really see much value in method naming or if a slash lives in a method or its caller. On the other hand you care about those things and can allow for 24h hours before getting feedback. It's hard to reconcile those two positions, but hopefully we'll manage.

  • e0ipso committed 5832a26 on 8.x-1.x authored by Wim Leers
    Issue #2949632 by Wim Leers, e0ipso, gabesullice: Make...
e0ipso’s picture

Status: Needs review » Fixed
wim leers’s picture

I don't really see much value in method naming or if a slash lives in a method or its caller.

I wouldn't care about this either if we weren't trying to get this into Drupal core.

I want to get things done right there and then because it's my only window of contribution.

I understand.

It's hard to reconcile those two positions, but hopefully we'll manage.

We always do! It's okay if things occasionally take longer.

I'll also push this commit to 2.x and then work on the blockers!

  • Wim Leers committed a95ecdb on 8.x-2.x
    Issue #2949632 by Wim Leers, e0ipso, gabesullice: Make...
wim leers’s picture

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.