Given I have a `ProductInterface` instance, how can I get the matching product URL for the current store using "stable" methods?
There is the `getProductUrl()` method on the product model, but I want to avoid using methods that are not part of an interface blessed with `@api` if possible.
I would be surprised if there where no clean way to get a product URL - seems like a common use case.
Does anybody have an idea?
Alan Storm just pointed me to his old question on StackExchange on the same topic.
After reading Chucks comment there It seems as if the core team thought there was no use case for product URLs...
But I assure you, there are many.
For example linking to a product page from an email (use case provided by Alan) or some affiliate tracking codes also require product URLs.
I think it could come up with more use cases that require a link to a product, but I don't want to add more here as that would just make me sound like I'm throwing another tantrum.
If there is no stable way to get a product URL that seems like quite an oversight. If there is, please point it out to me and I'll be very happy to spread the knowledge! It sure isn't obvious how to get at the product URL without using the ORM model (icky).
You're right in that currently there's not a clean/stable way to using the API to fetch the product URL. It's on our backlog to implement, but there's some groundwork that needs to be laid first to make this possible.
Out of curiosity mkotov -- what groundwork are you talking about? From the outside looking in, it seems like all that's required is
1. Adding a getProductUrl method to the interface
2. In the concrete class have getProductURL pass through the the product model's getProductUrl (with maybe some extra parameters/env setup for store id and website ids)
3. Mark the methods with `@api`
What other work could be needed there? The core application code already getProductUrl all over the place -- all you'd be doing is blessing the current usage.
I know the dangers of speculating on an internal development process, but if someone's pitching a lot of groundwork for a seemingly simple feature it seems like maybe they misunderstood the request?
Or am I missing something obvious?
Regarding the groundwork for adding Product URL to the ProductInterface.
For now Magento Data interfaces contain entity's data, and Service Contracts operate with these data. We don't have services for presentation layer.
Similar issue we have in Customer module, where CustomerInterface provides dedicated methods getFirstname() and getLastname() but most of the business logic needs specific representation – full name (which is a composition of Firstname + Lastname), so we have a Helper
And most of the external modules use this helper to get full name. So, in fact modules are dependent on "private" implementation, but not on the Customer's service contract which is wrong.
Here is the same story with Product URL, as URL is not data, but some kind of data representation. Moreover, URL doesn't represent just product data, as "base_url" part belongs to configuration, so product agnostic.
Adding Product URL to ProductInterface actually means - introducing of concept read-only attributes to our Data Interfaces. As we can't allow to modify product URL by direct setter function call through the ProductInterface. Which is not supported on the level of framework now.
As a long term solution – Query API should answer this question, as they will provide ability for read-only and computed fields.
As a solution we could provide for community nearest time – we could implement dedicated URL resolver service which will return URL for specific entity types (like Product, Category etc.)
Only canonical url would be returned (e.g. for products non-canonical url with category information can be presented: category-name/product-name.html).
That will introduce additional service call in business logic, but comply with our service contract guides