J4.x

Difference between revisions of "Adding an API to a Joomla Component"

From Joomla! Documentation

m (J4 label and category added)
(Marked for translation)
Line 1: Line 1:
 +
<noinclude><languages /></noinclude>
 
<noinclude>{{Joomla version|version=4.0}}</noinclude>
 
<noinclude>{{Joomla version|version=4.0}}</noinclude>
This page is intended to document how to integrate the API layer introduced in {{jver|4.0}} into your existing Joomla component. This assumes that you are using the default Joomla MVC layer
+
<translate>This page is intended to document how to integrate the API layer introduced in {{jver|4.0}} into your existing Joomla component. This assumes that you are using the default Joomla MVC layer</translate>
  
  
''' API integration for weblinks extension as an example '''
+
<translate>''' API integration for weblinks extension as an example '''</translate>
  
Repository extension: https://github.com/joomla-extensions/weblinks
+
<translate>Repository extension:</translate> https://github.com/joomla-extensions/weblinks
  
 
Pull request: https://github.com/joomla-extensions/weblinks/pull/407
 
Pull request: https://github.com/joomla-extensions/weblinks/pull/407
  
== First step ==
+
<translate>== First step ==</translate>
  
1. Create a folder '''''src/api'''''
+
1. <translate>Create a folder</translate> '''''src/api'''''
  
 
[[File:Struct1.png|500px|thumb|center|File system structure]]
 
[[File:Struct1.png|500px|thumb|center|File system structure]]
  
2. Create a class '''''WeblinksController'''''
+
2. <translate>Create a class</translate> '''''WeblinksController'''''
 
<source lang="php">
 
<source lang="php">
 
use Joomla\CMS\MVC\Controller\ApiController;
 
use Joomla\CMS\MVC\Controller\ApiController;
Line 27: Line 28:
 
</source>
 
</source>
  
Override the following fields:
+
<translate>Override the following fields:</translate>
  
  $contentType - will be used as default for $modelName as well when outputting response as type object
+
  $contentType - <translate>will be used as default for $modelName as well when outputting response as type object</translate>
  $default_view - will be used as default for $viewName
+
  $default_view - <translate>will be used as default for $viewName</translate>
  
3. Create a class '''''JsonApiView.php'''''
+
3. <translate>Create a class</translate> '''''JsonApiView.php'''''
  
 
<source lang="php">
 
<source lang="php">
Line 57: Line 58:
 
</source>
 
</source>
  
Override the following fields:
+
<translate>Override the following fields:</translate>
  
  $fieldsToRenderItem - array of fields to display a single object
+
  $fieldsToRenderItem - <translate>array of fields to display a single object</translate>
  $fieldsToRenderList - array of fields for listing objects
+
  $fieldsToRenderList - <translate>array of fields for listing objects</translate>
  
== Second step ==
+
<translate>== Second step ==</translate>
  
1. Create a folder '''''plugins/webservices/weblinks'''''
+
1. <translate>Create a folder</translate> '''''plugins/webservices/weblinks'''''
  
 
[[File:Struct2.png.png|500px|thumb|center|File system structure]]
 
[[File:Struct2.png.png|500px|thumb|center|File system structure]]
  
2. In the '''''weblinks.php''''', create the class '''''PlgWebservicesWeblinks'''''
+
2. <translate>In the '''''weblinks.php''''', create the class</translate> '''''PlgWebservicesWeblinks'''''
 
<source lang="php">
 
<source lang="php">
 
use Joomla\CMS\Plugin\CMSPlugin;
 
use Joomla\CMS\Plugin\CMSPlugin;
Line 82: Line 83:
 
</source>
 
</source>
  
In the '''''onBeforeApiRoute''''' method, register all the routes that we need for webservice.
+
<translate>In the '''''onBeforeApiRoute''''' method, register all the routes that we need for webservice.</translate>
  
3. Create '''''weblinks.xml'''''
+
3. <translate>Create</translate> '''''weblinks.xml'''''
 
<source lang="xml">
 
<source lang="xml">
 
<?xml version="1.0" encoding="utf-8"?>
 
<?xml version="1.0" encoding="utf-8"?>
Line 106: Line 107:
 
</source>
 
</source>
  
4. Create files '''''en-GB/en-GB.plg_webservices_weblinks.ini''''', '''''en-GB/en-GB.plg_webservices_weblinks.sys.ini''''' with next content:
+
4. <translate>Create files</translate> '''''en-GB/en-GB.plg_webservices_weblinks.ini''''', '''''en-GB/en-GB.plg_webservices_weblinks.sys.ini''''' <translate>with next content:</translate>
 
<source lang="php">
 
<source lang="php">
 
; Joomla! Project
 
; Joomla! Project
Line 117: Line 118:
 
</source>
 
</source>
  
== Third step  ==
+
<translate>== Third step  ==</translate>
1. In the file '''''src/administrator/components/com_weblinks/weblinks.xml''''' add a description for the API files
+
1. <translate>In the file</translate> '''''src/administrator/components/com_weblinks/weblinks.xml''''' <translate>add a description for the API files</translate>
 
<source lang="xml">
 
<source lang="xml">
 
<api>
 
<api>
Line 127: Line 128:
 
</source>
 
</source>
  
2. In the file  '''''src/administrator/manifests/packages/pkg_weblinks.xml''''' add a description for webservice plugin
+
2. <translate>In the file</translate> '''''src/administrator/manifests/packages/pkg_weblinks.xml''''' <translate>add a description for webservice plugin</translate>
 
<source lang="xml">
 
<source lang="xml">
 
<files>
 
<files>
Line 152: Line 153:
 
</source>
 
</source>
  
We use the ready-made component '''''com_categories''''', just need to pass the parameter 'extension' => 'com_weblinks'
+
<translate>We use the ready-made component '''''com_categories''''', just need to pass the parameter 'extension'</translate> => 'com_weblinks'
  
== Fields ==
+
<translate>== Fields ==</translate>
1. Add fields and fields groups support for weblinks webservice. Edit the file '''''src/plugins/webservices/weblinks/weblinks.php'''''
+
1. <translate>Add fields and fields groups support for weblinks webservice. Edit the file</translate> '''''src/plugins/webservices/weblinks/weblinks.php'''''
 
<source lang="php">
 
<source lang="php">
 
class PlgWebservicesWeblinks extends CMSPlugin
 
class PlgWebservicesWeblinks extends CMSPlugin
Line 177: Line 178:
 
</source>
 
</source>
  
2. Override the function '''''save''''' in '''''WeblinksController'''''
+
2. <translate>Override the function</translate> '''''save''''' <translate>in</translate> '''''WeblinksController'''''
 
<source lang="php">
 
<source lang="php">
 
class WeblinksController extends ApiController
 
class WeblinksController extends ApiController
Line 207: Line 208:
 
</source>
 
</source>
  
3. Override the functions '''''displayList, displayItem, prepareItem''''' in '''''Weblinks\JsonApiView'''''
+
3. <translate>Override the functions</translate> '''''displayList, displayItem, prepareItem''''' <translate>in</translate> '''''Weblinks\JsonApiView'''''
  
 
<source lang="php">
 
<source lang="php">
Line 248: Line 249:
 
</source>
 
</source>
  
Pay attention in function prepareItem to <source lang="php">$field->apivalue</source> If the type of the field is complex, we hope that it will return a value for output in the API component, otherwise we will take <source lang="php">$field->rawvalue</source>
+
<translate>Pay attention in function prepareItem to <source lang="php">$field->apivalue</source> If the type of the field is complex, we hope that it will return a value for output in the API component, otherwise we will take </translate>
 +
<source lang="php">$field->rawvalue</source>
  
== Integration Work Example ==
+
<translate>== Integration Work Example ==</translate>
'''''NOTE: Remember to enable weblinks webservice plugin!'''''
+
'''''<translate>NOTE: Remember to enable weblinks webservice plugin!</translate>'''''
  
=== Weblinks ===
+
<translate>=== Weblinks ===</translate>
==== Get List of Weblinks ====
+
<translate>==== Get List of Weblinks ====</translate>
 
curl -X GET /api/index.php/v1/weblinks
 
curl -X GET /api/index.php/v1/weblinks
  
==== Get Single Weblink ====
+
<translate>==== Get Single Weblink ====</translate>
 
curl -X GET /api/index.php/v1/weblinks/{weblink_id}
 
curl -X GET /api/index.php/v1/weblinks/{weblink_id}
  
==== Delete Weblink ====
+
<translate>==== Delete Weblink ====</translate>
 
curl -X DELETE /api/index.php/v1/weblinks/{weblink_id}
 
curl -X DELETE /api/index.php/v1/weblinks/{weblink_id}
  
==== Create Weblink ====
+
<translate>==== Create Weblink ====</translate>
 
curl -X POST -H "Content-Type: application/json" /api/index.php/v1/weblinks -d  
 
curl -X POST -H "Content-Type: application/json" /api/index.php/v1/weblinks -d  
 
<source lang="javascript">
 
<source lang="javascript">
Line 301: Line 303:
 
</source>
 
</source>
  
==== Update Weblink ====
+
<translate>==== Update Weblink ====</translate>
 
curl -X PUT -H "Content-Type: application/json" /api/index.php/v1/weblinks/{weblink_id} -d  
 
curl -X PUT -H "Content-Type: application/json" /api/index.php/v1/weblinks/{weblink_id} -d  
 
<source lang="javascript">
 
<source lang="javascript">
Line 313: Line 315:
 
</source>
 
</source>
  
=== Categories ===
+
<translate>=== Categories ===</translate>
Route Weblinks Categories is: "v1/weblinks/categories"
+
<translate>Route Weblinks Categories is:</translate> "v1/weblinks/categories"
  
Working with it is similar to [[J4.x:Joomla_Core_APIs#Categories|Banners Categories]].
+
<translate>Working with it is similar to</translate> [[J4.x:Joomla_Core_APIs#Categories|Banners Categories]].
  
=== Fields ===
+
<translate>=== Fields ===</translate>
  
Route Fields Weblinks is: "v1/fields/weblinks"
+
<translate>Route Fields Weblinks is:</translate> "v1/fields/weblinks"
  
Working with it is similar to [[J4.x:Joomla_Core_APIs#Fields_Contact|Fields Contact]].
+
<translate>Working with it is similar to</translate> [[J4.x:Joomla_Core_APIs#Fields_Contact|Fields Contact]].
  
=== Groups Fields ===
+
<translate>=== Groups Fields ===</translate>
  
Route Groups Fields Weblinks is: "v1/fields/groups/weblinks"
+
<translate>Route Groups Fields Weblinks is:</translate> "v1/fields/groups/weblinks"
  
Working with it is similar to [[J4.x:Joomla_Core_APIs#Groups_Fields_Contact|Groups Fields Contact]].
+
<translate>Working with it is similar to</translate> [[J4.x:Joomla_Core_APIs#Groups_Fields_Contact|Groups Fields Contact]].
  
  
 
<noinclude>
 
<noinclude>
[[Category:Development]]
+
[[Category:Development{{#translation:}}]]
[[Category:Joomla!_Api]]
+
[[Category:Component_Development{{#translation:}}]]
[[Category:Joomla!_4.x]]
+
[[Category:Joomla!_Api{{#translation:}}]]
 +
[[Category:Joomla!_4.x{{#translation:}}]]
 
</noinclude>
 
</noinclude>

Revision as of 05:06, 17 October 2020

Other languages:
Deutsch • ‎English • ‎français
Joomla! 
4.0

This page is intended to document how to integrate the API layer introduced in Joomla 4.0 into your existing Joomla component. This assumes that you are using the default Joomla MVC layer


API integration for weblinks extension as an example

Repository extension: https://github.com/joomla-extensions/weblinks

Pull request: https://github.com/joomla-extensions/weblinks/pull/407

First step[edit]

1. Create a folder src/api

File system structure

2. Create a class WeblinksController

use Joomla\CMS\MVC\Controller\ApiController;

class WeblinksController extends ApiController 
{
    protected $contentType = 'weblinks';

    protected $default_view = 'weblinks';
}

Override the following fields:

$contentType - will be used as default for $modelName as well when outputting response as type object
$default_view - will be used as default for $viewName

3. Create a class JsonApiView.php

use Joomla\CMS\MVC\View\JsonApiView as BaseApiView;

class JsonApiView extends BaseApiView
{
    protected $fieldsToRenderItem = [
        'id',
        'catid',
        'title',
        'alias',
        'url',
        'xreference',
        'tags',
    ];

    protected $fieldsToRenderList = [
        'id',
        'title',
        'alias',
    ];
}

Override the following fields:

$fieldsToRenderItem - array of fields to display a single object
$fieldsToRenderList - array of fields for listing objects

Second step[edit]

1. Create a folder plugins/webservices/weblinks

File system structure

2. In the weblinks.php, create the class PlgWebservicesWeblinks

use Joomla\CMS\Plugin\CMSPlugin;
use Joomla\CMS\Router\ApiRouter;

class PlgWebservicesWeblinks extends CMSPlugin
{
    public function onBeforeApiRoute(&$router)
    {
        $router->createCRUDRoutes('v1/weblinks', 'weblinks', ['component' => 'com_weblinks']);
    }
}

In the onBeforeApiRoute method, register all the routes that we need for webservice.

3. Create weblinks.xml

<?xml version="1.0" encoding="utf-8"?>
<extension version="3.1" type="plugin" group="webservices" method="upgrade">
    <name>plg_webservices_weblinks</name>
    <author>Joomla! Project</author>
    <creationDate>August 2017</creationDate>
    <copyright>(C) 2005 - 2019 Open Source Matters. All rights reserved.</copyright>
    <license>GNU General Public License version 2 or later; see LICENSE.txt</license>
    <authorEmail>admin@joomla.org</authorEmail>
    <authorUrl>www.joomla.org</authorUrl>
    <version>4.0.0</version>
    <description>PLG_WEBSERVICES_WEBLINKS_XML_DESCRIPTION</description>
    <files>
         ##FILES##
    </files>
    <languages folder="administrator/language">
         ##LANGUAGE_FILES##
    </languages>
</extension>

4. Create files en-GB/en-GB.plg_webservices_weblinks.ini, en-GB/en-GB.plg_webservices_weblinks.sys.ini with next content:

; Joomla! Project
; Copyright (C) 2005 - 2019 Open Source Matters. All rights reserved.
; License GNU General Public License version 2 or later; see LICENSE.txt, see LICENSE.php
; Note : All ini files need to be saved as UTF-8

PLG_WEBSERVICES_WEBLINKS="Web Services - Weblinks"
PLG_WEBSERVICES_WEBLINKS_XML_DESCRIPTION="Used to add weblinks routes to the API for your website."

Third step[edit]

1. In the file src/administrator/components/com_weblinks/weblinks.xml add a description for the API files

<api>
    <files folder="api/components/com_weblinks">
       ##API_COMPONENT_FILES##
    </files>
</api>

2. In the file src/administrator/manifests/packages/pkg_weblinks.xml add a description for webservice plugin

<files>
    ...
    <file type="plugin" id="weblinks" group="webservices">plg_webservices_weblinks.zip</file>
</files>

Categories[edit]

1. Add categories support for weblinks webservice. Edit the file src/plugins/webservices/weblinks/weblinks.php

class PlgWebservicesWeblinks extends CMSPlugin
{
    public function onBeforeApiRoute(&$router)
    {
        ...
        $router->createCRUDRoutes(
            'v1/weblinks/categories',
            'categories',
            ['component' => 'com_categories', 'extension' => 'com_weblinks']
        );
    }
}

We use the ready-made component com_categories, just need to pass the parameter 'extension' => 'com_weblinks'

Fields[edit]

1. Add fields and fields groups support for weblinks webservice. Edit the file src/plugins/webservices/weblinks/weblinks.php

class PlgWebservicesWeblinks extends CMSPlugin
{
    public function onBeforeApiRoute(&$router)
    {
        ...
        $router->createCRUDRoutes(
            'v1/fields/weblinks',
            'fields',
            ['component' => 'com_fields', 'context' => 'com_weblinks.weblink']
        );

        $router->createCRUDRoutes(
            'v1/fields/groups/weblinks',
            'groups',
            ['component' => 'com_fields', 'context' => 'com_weblinks.weblink']
        );
    }
}

2. Override the function save in WeblinksController

class WeblinksController extends ApiController
{
    ...

    protected function save($recordKey = null)
    {
        $data = (array) json_decode($this->input->json->getRaw(), true);

        foreach (FieldsHelper::getFields('com_weblinks.weblink') as $field)
        {
            if (isset($data[$field->name]))
            {
                !isset($data['com_fields']) && $data['com_fields'] = [];

                $data['com_fields'][$field->name] = $data[$field->name];
                unset($data[$field->name]);
            }
        }

        $this->input->set('data', $data);

        return parent::save($recordKey);
    }

    ...
}

3. Override the functions displayList, displayItem, prepareItem in Weblinks\JsonApiView

class JsonApiView extends BaseApiView
{
    ...

    public function displayList(array $items = null)
    {
        foreach (FieldsHelper::getFields('com_weblinks.weblink') as $field)
        {
            $this->fieldsToRenderList[] = $field->name;
        }

        return parent::displayList();
    }

    public function displayItem($item = null)
    {
        foreach (FieldsHelper::getFields('com_weblinks.weblink') as $field)
        {
            $this->fieldsToRenderItem[] = $field->name;
        }

        return parent::displayItem();
    }

    protected function prepareItem($item)
    {
        foreach (FieldsHelper::getFields('com_weblinks.weblink', $item, true) as $field)
        {
            $item->{$field->name} = isset($field->apivalue) ? $field->apivalue : $field->rawvalue;
        }

        return parent::prepareItem($item);
    }

    ...
}

Pay attention in function prepareItem to

$field->apivalue

If the type of the field is complex, we hope that it will return a value for output in the API component, otherwise we will take

$field->rawvalue

Integration Work Example[edit]

NOTE: Remember to enable weblinks webservice plugin!

Weblinks[edit]

Get List of Weblinks[edit]

curl -X GET /api/index.php/v1/weblinks

Get Single Weblink[edit]

curl -X GET /api/index.php/v1/weblinks/{weblink_id}

Delete Weblink[edit]

curl -X DELETE /api/index.php/v1/weblinks/{weblink_id}

Create Weblink[edit]

curl -X POST -H "Content-Type: application/json" /api/index.php/v1/weblinks -d

{
    "access": "1",
    "alias": "",
    "catid": "8",
    "description": "<p>text</p>",
    "images": {
        "float_first": "",
        "float_second": "",
        "image_first": "",
        "image_first_alt": "",
        "image_first_caption": "",
        "image_second": "",
        "image_second_alt": "",
        "image_second_caption": ""
    },
    "language": "*",
    "metadata": {
        "rights": "",
        "robots": ""
    },
    "metadesc": "",
    "metakey": "",
    "modified": "",
    "params": {
        "count_clicks": "",
        "height": "",
        "target": "",
        "width": ""
    },
    "title": "weblink title",
    "url": "http://somelink.com/",
    "xreference": "xreference"
}

Update Weblink[edit]

curl -X PUT -H "Content-Type: application/json" /api/index.php/v1/weblinks/{weblink_id} -d

{
    "catid": "8",
    "description": "<p>some new text</p>",
    "language": "*",
    "title": "new title",
    "url": "http://newsomelink.com/"
}

Categories[edit]

Route Weblinks Categories is: "v1/weblinks/categories"

Working with it is similar to Banners Categories.

Fields[edit]

Route Fields Weblinks is: "v1/fields/weblinks"

Working with it is similar to Fields Contact.

Groups Fields[edit]

Route Groups Fields Weblinks is: "v1/fields/groups/weblinks"

Working with it is similar to Groups Fields Contact.