Magento 2 GraphQL API is a fully-featured GraphQL (watch video) server on top of the Magento 2 Service Contracts. It allows to easily consume Magento APIs through the GraphQL clients, such as Apollo. Also, it allows creating GraphQL APIs in 3-d party Magento extensions, in order to expose custom extension data to the GraphQL clients. The primary use-case for such APIs is javascript clients which implement re-usable UI building blocks (Web Components) and use Magento in a headless way.
To get started with the M2 GraphQL go to Magento 2 GraphiQL demo page Magento 2 GraphiQL Playground which works on top of the store withs the sample data.
Magento 2 GraphQL server endpoint can be used by any GraphQL client. It:
- Exposes Magento 2 Web REST APIs with the GraphQL interface
- Installed as an extension on Magento 2 and does not require core customizations
- Uses webonyx/graphql-php library which implements all server-side features of the GraphQL language
- Allows traffic optimization for the client applications transferring just the data needed in particular use-case. Allows combining multiple API requests in a single request.
- Supports Magento 2 API authentication model and exposes just the data client authorized to see
- Supports flexible deprecation model informing clients on usage of deprecated fields
Investigate GraphQL API and come up with the best design for the M2 GraphQL schema. Use playground, experiment and share what you liked! Feedback and ides are welcome. Please join #pwa slack channel for the most efficient discussions.
Alan Kent is doing exploration project with slightly different approach: instead of using current Magento APIs as a base for GraphQL schema, the schema for GraphQL is deisgned from the scratch, getting it directly to the desired end state of the GraphQL API, and Magento API will be changed (or re-implemented) accordingly. At the end, we will take the best of both approaches. Current repository allows to play with all the Magento API data immediatedly, while Alan's is focused on how to make the requests most convenient.
Read more in Dev Blog
"repositories": [
{
"type": "vcs",
"url": "https://github.com/vrann/m2graphql"
}
],
Set minimum-stability to dev:
"minimum-stability": "dev"
composer require vrann/m2graphql:dev-master
bin/magento module:enable Magento_GraphQL
bin/magento setup:upgrade
- in the browser, go to the
http://magento-base-url/graphql
and you expected to see properly formed JSON document
The easiest way to try GraphQL API is to install GraphiQL user interface either as app or Chrome ChromeiQL extension to the browser. The Appolo Client DevTools allows to install developer tools in the Chrome console.
Production application which uses GraphQL can be written on any supported language. In this document all, examples will be using javascript and the Apollo client.
Following is an excerpt of Apollo documentation:
import ApolloClient, { createNetworkInterface } from 'apollo-client';
import gql from 'graphql-tag';
const client = new ApolloClient({
networkInterface: createNetworkInterface({
uri: 'https://m2instance.dev/graphql',
}),
});
Replace https://m2instance.dev
with the base path of the Magento instance here package is installed.
To execute a query with your client you may now call the client.query
method like this:
client.query({
query: gql`
query MagentoCatalogProduct(sku: "CannondaleCaad1032014"){
id, name, price, media_gallery_entries {
file
}, custom_attributes {
attribute_code,
value
}
}
`,
})
.then(data => console.log(data))
.catch(error => console.error(error));
If you worked with the Magento Service layer, you should already be familiar with the concept of authorization, Service Interfaces, Data Interfaces, REST routing. Otherwise, please read following materials:
M2GraphQL extension works on top of the Magento Webapi framework and re-uses the same infrastructure, that's why most of the concepts will work in the same way.
At the same time, GraphQL schema design conventions have certain assumptions which do not directly correspond to the Service contracts. One example -- fields of the Query root object are expected to be Objects, and they can accept filters as parameters of the query to the data retrieval layer. While root objects of the Service contracts are operations, which can accept the input Object of operation. In order to make the transition of the Service Contracts to GraphQL paradigm, following rules were used:
- All GET requests are exposed as fields of the Query object
- For particular GET request, the type of the corresponding field is constructed using the name of the result object (declared in @return annotation) of the related service interface method.
- The parameters of the field are taken from the parameters of the service interface method corresponding to GET request
- Input and output parameters are constructed from the input object replacing \ with _
- Input parameters has _Input suffix
webapi.xml
<route url="/V1/products/:sku" method="GET">
<service class="Magento\Catalog\Api\ProductRepositoryInterface" method="get"/>
<resources>
<resource ref="Magento_Catalog::products" />
</resources>
</route>
RepositoryInterface
/**
* Get info about product by product SKU
*
* @param string $sku
* @param bool $editMode
* @param int|null $storeId
* @param bool $forceReload
* @return \Magento\Catalog\Api\Data\ProductInterface
* @throws \Magento\Framework\Exception\NoSuchEntityException
*/
public function get($sku, $editMode = false, $storeId = null, $forceReload = false);
Resulting GraphQL schema
MagentoCatalogProduct(
sku: String
editMode: Boolean
storeId: Int
forceReload: Boolean
): Magento_Catalog_Api_Data_ProductInterface
MagentoCmsBlockSearchResults(
searchCriteria: Magento_Framework_Api_SearchCriteriaInterface_Input
): Magento_Cms_Api_Data_BlockSearchResultsInterface
This is Work In Progress
This is an example of simple request to retrieve 3 fields from a Store object:
MagentoStoreStores{id, name, code}
This is an example of filter parameters passed to the root object:
MagentoCatalogProduct(sku: "CannondaleCaad1032014"){
id, name, price, media_gallery_entries {
file
}, custom_attributes {
attribute_code,
value
}
}
Example of the getList query with the SearchCriteria:
MagentoCmsBlockSearchResults(searchCriteria: {
sort_orders: {
field: "block_id",
direction: "ASC"
}
filter_groups: {
filters: {
field: "block_id",
value: "1",
condition_type: "eq"
}
}
}){
items{id, title, content}
}
Custom attributes is an array of Attributes in the data interfaces corresponding to EAV entities which represent values of EAV attributes. You can find examples of custom attributes on the ProductInetrafce, CustomerInterface, etc
Custom attributes are not filterable and represented as an array of all attributes available for the entity. In order to make retrieval of custom attributes more efficient, filtration syntax is added.
Now, in order to request specific attribute under EAV entity interface, specify filter request: filter:["attribute_code"]
Example:
MagentoCatalogProductSearchResults(searchCriteria:{
filter_groups: {
filters: {
field: "sku",
value: "MH12",
condition_type: "in"
}
},
page_size:10,
current_page: 0
}){
items {
id,
name,
price,
custom_attributes(
filter:["thumbnail"]
) {
attribute_code,
value
}
}
}
The examples directory examples/react-product-webcomponent contains sample React application which loads Magento Product from the GraphQL API and renders as a javascript widget
See demo here: http://m2graphql.com/sampleapp/index.html
- Clone this repository
cd examples/react-product-webcomponent
- open index.html in browser