2015-07-24

In this post I work through a working example of how to create a new REST web service in Magento 2. My goal is to show how easy it is define a new RESTful service. The examples start with a simple integers, moves on to arrays, then ends with a more complex data type to pass into and return from a service call. This post focusses on JSON, but REST with XML and SOAP are also supported by Magento 2. Full documentation can be found on http://devdocs.magento.com under the “Web Services Developer”.

To keep the following examples as simple as possible, the new APIs perform some mathematical operations on input parameters. There are no database tables for storage, and no authentication. (Magento 2 supports three forms of authentication, as described in the full documentation on the site. The three forms are suitable for AJAX calls from the user’s web session, from a mobile device, and from an external application where an authentication token must be stored in a file on disk.)

Example 1: Add 2 Numbers

The first example is to add two integers, where the two arguments are passed on the URL. This illustrates how to extract parameters from the URL, and shows a very simple function prototype. I will show all the files first, then explain some of the less obvious points. Some parts are omitted as they will be introduced below in later steps.

I used the vendor name “AlanKent” for my module, with a module name of “CalculatorWebService”.

app/code/AlanKent/CalculatorWebService/etc/module.xml

app/code/AlanKent/CalculatorWebService/etc/di.xml

app/code/AlanKent/CalculatorWebService/etc/webapi.xml

app/code/AlanKent/CalculatorWebService/Api/CalculatorInterface.php

app/code/AlanKent/CalculatorWebService/Model/Calculator.php

Description

The above is the complete definition of a new module exposing a new REST web service to add two numbers. Briefly the files have the following purposes.

etc/module.xml – declares the module, it’s name, it’s dependencies, and it’s DB schema version (currently needed even if there is no DB).

etc/di.xml – declares that any request for the calculator service contract interface can be satisfied by instantiating the calculator class. (Other modules could swap in a new implementation by overriding this preference.

etc/webapi.xml – binds a URL with two parameters as path segments to the add() method of the calculator interface. “Resources” is the Magento terminology for access control lists – “anonymous” means anyone can access the service.

Api/CalculatorInterface.php – declares a PHP interface with an add(num1, num2) method. Note that the PHP doc for the method is very important, as it is used to determine the types of the function arguments and return value.

Model/Calculator.php – declares a class implementing the interface (it actually implements the add() function).

The Magento framework will then parse the URL, extract the arguments from the URL, and provide as arguments to the add() function call. Here is a sample of running the service using CURL.

The return value will be “3”, rather than a full JSON object. This is because the return value is a simple type (an integer).

Note there is no code required to serialize or deserialize JSON – that is done by the Magento framework. The same code will work with SOAP by changing the etc/webapi.xml file.

And that is it. A complete definition of a module that defines a web service for other applications to access in 5 fairly short files.

Example 2: Sum an Array of Floating-point Numbers

Let’s now add a new method where we POST a JSON object holding an array of values to be added up, with the total sum returned. This is fairly straightforward, as Magento knows also how to encode/decode arrays and objects as well. The additional lines are highlighted in bold.

app/code/AlanKent/CalculatorWebService/etc/webapi.xml

app/code/AlanKent/CalculatorWebService/Api/CalculatorInterface.php

app/code/AlanKent/CalculatorWebService/Model/Calculator.php

Description

As can be seen, you simply add a new method to the interface and class implementing the interface, then add a new route in the webapi.xml file to bind a URL to the new sum() method.  This new service can be invoked as follows:

Instead of passing parameters on the URL, this example sends a JSON object with a HTTP POST to the specified URL. The arguments are encoded in a JSON object, with a field per function call parameter. In this case, the function sum() is declared with a single parameter “nums” (see the interface definition) which is an array of floating point numbers. The framework again does all the JSON parsing of input data and encoding of the return value, handling a range of simple types..

Example 3: Mid-point Between two Points

As an example of passing in and returning a more complex JSON object, consider a function midPoint() that takes two Point instances (holding x and y coordinate values) and returns a new Point instance that represents the mid-point between the two coordinates. Again, I will show the code first with changes from example 2 in bold.

app/code/AlanKent/CalculatorWebService/etc/di.xml

app/code/AlanKent/CalculatorWebService/etc/webapi.xml

app/code/AlanKent/CalculatorWebService/Api/CalculatorInterface.php

app/code/AlanKent/CalculatorWebService/Api/Data/PointInterface.php

app/code/AlanKent/CalculatorWebService/Model/Calculator.php

app/code/AlanKent/CalculatorWebService/Model/Point.php

Description

To invoke the service using CURL, you can use the following command.

The -d option causes CURL to do a POST of the provided JSON object (two arguments called point1 and point2). The returned object is also a Point instance with x and y coordinates. Running quickly through the changes again,

etc/di.xml – adds the class reference for Points.

etc/webapi.xml – adds the new URL to function call binding.

Api/CalculatorInterface.php – adds the new mid-point function.

Api/Data/PointInterface.php – an important new file, acting as the definition of the encoding and decoding of JSON objects. This class is in the Api/Data directory to identify it as an interface for holding a data structure for function call arguments and/or return values.

Module/Calculator.php – has the new method added, but also now has a constructor that takes a ‘PointInterfaceFactory’ argument. I have not supplied this file as the Magento framework will automatically create the class for us. It will have a single create() method that returns an instance of the requested Point instance, but calling the Magento object manager (which will examine the di.xml file to work out the right class to create for PointInterface).

Module/Point.php – contains setters and getters to manipulate a ‘Point’ instance (an x, y pair).

Conclusions

This post does not try to explain every concept with writing a web service – please see the online documentation http://devdocs.magento.com/ for that. The goal of this was to provide a few simple examples of writing your own web service, to demonstrate how easy it is to define a new set of functions and expose them as REST (or SOAP) web services. I did not cover how to use SOAP instead of REST+JSON, and I also did not cover how authentication works. Please consult the manuals for this additional information.

Show more