Services API Development Guide

From MythTV Official Wiki
Revision as of 21:37, 5 June 2020 by Pgbennett (talk | contribs) (New topic)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Services API Development Guide

This is a guide to developers on adding a new service API method to mythbackend. This may also be applicable to mythfrontend.

Introduction

The service api uses a framework that takes care of all of the details involved in receiving, formatting and sending responses. Using this framework it is easy to add new API methods that automatically support SOAP and REST, and support both json and XML responses.

Code to perform the method

The new method will typically either perform some sort of update, or retrieve some sort of data. The first step is to have a way of performing the operation. You may need to write a method in the scheduler or in a utility module such as mythutil.cpp. It will take some parameters as supplied in the call and provide some sort of response.

Choose your service

Make a determination which service your new method will run under. This is a logical determination. There is no technical or programmatic difference in where you place it. The services are Capture. Channel, Content. Dvr, Guide. Myth, Video, Rtti. You can see the latest list by looking in mythtv/libs/libmythservicecontracts/services/.

Review the methods in existing services using the URL example http://backend:6544/Video/wsdl to see if your new method fits in with the types of methods in a particular service. For example, the Content service provides methods for downloading files so if that is your purpose, the Content service should be used.

Decide on your input and output

The input to a service may be nothing at all, or may be a set of field values. The response may be a single vale (e.g. true or false) or it could be a complex structure with repeating groups. If you are using repeating groups, you can save effort and improve consistency by using existing structures. For example, many service APIs use the ArtworkInfoList structure to return file names and urls of image files. You can test the existing services using a browser or the curl command to see what their response looks like. Methods that require POST will have to be tested with curl.

When testing apis with curl, the XML output will be all strung together with no line endings, and very difficult to read. You can install an xml pretty printer to format the xml in a readable way. For example, geany has a plugin geany-plugin-prettyprinter.

Decide on the HTTP Method

If your new method makes any type of change at the server, it should use the POST HTTP method. If it only retrieves information it should use GET.

Code the return structure

If the new method returns a simple true or false or a number, skip this step.

If the new method returns an existing structure (i.e. the same as some other method in any service), skip this step.

If you have a repeating structure (that is not an existing structure) in the response, create a new header file for the data to be repeated, named for the repeating structure name. This header file goes in mythtv/libs/libmythservicecontracts/datacontracts/, for example mythtv/libs/libmythservicecontracts/datacontracts/videoStreamInfo.h. Copy one of the existing files there (for example videoStreamInfo.h) and make it into your own. Each field of the response is defined with two macros: Q_PROPERTY, PROPERTYIMP, and initialized in the constructor and copied in the Copy method. Include the InitializeCustomTypes method as in the existing header files.

Create a new header file for the response itself, in the same directory, with a logical name,for example mythtv/libs/libmythservicecontracts/datacontracts/videoStreamInfoList.h. Inside this file should be an include for the repeating structure header, if applicable. Clone this file from an appropriate header, for example videoStreamInfoList.h. This file defines all of the fields in the non-repeating part of your response, plus a QVariantList to reference the repeating part, if applicable.

Add the new header files to mythtv/libs/libmythservicecontracts/libmythservicecontracts.pro in two places.

Declare the new method

Each service has a header file in mythtv/libs/libmythservicecontracts/services/, for example mythtv/libs/libmythservicecontracts/services/videoServices.h. If you created a header file for your response, add the include. Add the new method in two places, in a call to InitializeCustomTypes (if you created a new header file), and a pure virtual method definition, with input parameters defined and the response structure in the return type.

If your method will use POST (i.e. it does some update), Add an entry Q_CLASSINFO( "xxx_Method", "POST" ). If it uses GET, skip this step.

Each service also has a header file in b/mythtv/programs/mythbackend/services/, for example b/mythtv/programs/mythbackend/services/video.h. Define a method here, that overrides the pure virtual method defined above.

Code the new method

Each service has a file in mythtv/programs/mythbackend/services/, for example a/mythtv/programs/mythbackend/services/video.cpp. Add the body of the method here. This will consist of a call to some code in MythTV to do the update or get the data, followed by code to put the data into the response. For an example that returns a data structure, see Video::GetStreamInfo in video.cpp. If there is a simple return such as true or false, just return that value.

Examples

Here are two examples of methods recently added:

DelayShutdown

This performs a simple update (prevent shutdown for 5 minutes). It takes no input parameter and simply returns true. To see the code changes that implement this:

git show ae82a5a58f

GetStreamInfo

This is a read-only method that gets stream info for a video or a recording. It takes 2 input parameters and returns a structure that includes a repeating group.

git show a2af89101b