This specification documents the RecipeRPC protocol, version 0.4. You can look at earlier versions here.

RecipeRPC is a protocol for supplying recipes to clients over a network from one or more central servers. It is:

Table of contents

XML-RPC
Sample session
Host name and URI
Usernames and passwords
Config method
Search method
Fetch method
Optional methods
Odds and ends
Earlier versions
Copyright and disclaimer

XML-RPC

RecipeRPC clients make remote procedure calls using XML-RPC. You should read the XML-RPC specification before reading this document. (Don't worry, it's short and simple.)

There are free or cheap XML-RPC libraries available for most major languages (PHP, C, Java, Perl, and more). Generally, these libraries make XML-RPC calls very simple to use - there's no need to mess about with HTTP requests. For example, with one such library for PHP, you write code like this to call the reciperpc.config() method:

$f=new xmlrpcmsg('reciperpc.config()',
                 array(new xmlrpcval("squirrel", "string"),
                       new xmlrpcval("mypassword", "string")));
$c=new xmlrpc_client("/RPC2", "reciperpc.sourceforge.net", 80);
$r=$c->send($f);
$v=$r->value();

Sample session

Here is an example of the messages that pass between a RecipeRPC client and a RecipeRPC server in a typical session. To keep the description clear and simple, this sample session shows neither fault handling nor handling of extended result lists. There are links to the detailed HTTP messages, if you need that level of detail (you shouldn't normally if you are using an XML-RPC library).

1A. Client calls the XML-RPC procedure

  reciperpc.config("squirrel", "mypassword")

Here is the HTTP request for this reciperpc.config() call.

1B. Server returns the struct

Key Value
version 0.4
description RecipeRPC Reference Implementation Server
criteria See below
formats [RecipeML, CookML]

The criteria member is itself a struct with these contents:

Key Value
name [any]
category [Vegetarian, Diabetic]

Here is the HTTP response for this reciperpc.config() call.

2A. Client calls the XML-RPC procedure

  reciperpc.search("squirrel", "mypassword", criteria, 1)

where criteria is the struct

Key Value
name lemon

Here is the HTTP request for this reciperpc.search() call.

2B. Server returns the struct

Key Value
total 2
recipes See below

in which recipes is an array containing these two structs:

Key Value
name #1 Lemon Bars
id 12345

and

Key Value
name 1-2-3 Lemon Pie
id 65432

Here is the HTTP response for this reciperpc.search() call.

3A. Client calls the XML-RPC procedure

  reciperpc.fetch("squirrel", "mypassword", 65432, "RecipeML")

Here is the HTTP request for this reciperpc.fetch() call.

3B. Server returns a base64 object, containing the "1-2-3 Lemon Pie" recipe in RecipeML format, as base64-encoded binary.

Here is the HTTP response for this reciperpc.fetch() call.

Host name and URI

An XML-RPC client needs only two things to connect to a server: the server's host name and a URI for that server. These are familiar objects, appearing in any web address: in the address for this page

http://reciperpc.sourceforge.net/spec.html
we have a host name of reciperpc.sourceforge.net and a URI of /spec.html. Basically, the host name tells you where to go on the Internet to get to the server, and the URI tells the server where to direct your request.

The host name of an XML-RPC server will almost always be its domain name. The standard URI for an XML-RPC server is /RPC2, but a server can use any convenient URI (including the trivial URI consisting only of a single slash / - you would normally only do this if your host is doing nothing but serving XML-RPC requests).

Clients may assume that servers are using port 80, the standard port for HTTP requests. Clients may support other ports; the port number will need to be supplied as part of the specification of the server.

Usernames and Passwords

Each method described below takes username and password parameters. These are strings with the obvious meanings and may be used by the server for authentication or ignored.

A client may, as a standard procedure, make its first call to the server with blank username and password. If fault 401, invalid username or password, is returned, the client should fetch a valid username and password (for instance, by prompting the user) and use it in future method calls to this server. If the server gives a valid response, the client may continue to use blank username and password in future method calls.

config method

struct reciperpc.config(string username, string password)

Description. Fetches configuration information about the RecipeRPC server.

Parameters. The username and password parameters have the standard types and meanings.

Return value. This struct:

Key Value type Value description
version string The version of RecipeRPC supported by this server.
description string Brief description of this server. May be used, for example, in a list of available servers.
criteria struct. See below. Identifiers for the criteria that can be used in searches. Examples: name, category, rating, equipment.
formats array of strings Names of the formats available from this server. Examples: RecipeML, MealMaster.

The criteria element of this struct is itself a struct, in which:

For clarity, servers should (but do not have to) return the array [any] to indicate that any value is acceptable for the criterion.

Faults. The server may return these faults:

Fault code Fault description
401 Invalid username or password.
5xx Implementation-specific faults.

search method

struct reciperpc.search(string username, string password, struct criteria, int index)

Description. Searches for recipes matching given criteria.

Parameters. The username and password parameters have the standard types and meanings.

The criteria parameter is a struct in which:

This struct may be empty (contain no keys) which should be interpreted as a request for all recipes from the server. The server may respond with an implementation-specific fault in this case, if such queries are not allowed.

For example, the sample criteria structure above indicates that the server should return vegetarian recipes with names containing "Spaghetti".

The index parameter is an int indicating the index of the first recipe to return. That is, if this parameter is set to n and the list of all recipes matching the criteria is numbered 1, 2, 3, ..., then the server should send recipes beginning with the one numbered n. If n is greater than the number of recipes matching the criteria, then the server should return fault 413.

Normally, the client will send the value 1 for this parameter on the first call to reciperpc.search(). If the server sends, say, only the first 25 matching recipes in response to this call, and if the client requires more recipes, the client will normally then call reciperpc.search() again with index equal to 26. If still more are required, repeat with 51, 76, 101, ....

Return value. This struct:

Key Value type Value description
total int The total number of recipes that match the criteria.
recipes array An array of recipe data. See below.

The recipes element of this struct is an array, possibly empty, of structs with this form:

Key Value type Value description
name string The name of a recipe matching the given criteria.
id string An identifier that uniquely identifies this recipe to the server.

Notice that the server need not return all matching recipes, but it must return the total number of matching recipes in the member total (naturally total may be zero if nothing matches). The client can easily determine whether there are any more recipes to be had: the server has sent all the recipes if and only if

total = index + size(recipes) - 1.

Faults. The server may return these faults:

Fault code Fault description
401 Invalid username or password.
413 Index greater than total number of matching recipes.
415 Invalid criterion name.
5xx Implementation-specific faults.

The list of implementation-specific faults should include one for each criterion with a list of valid values, with a description like
'Begetarian' is not a valid search value for the criterion 'category'.

fetch method

base64 reciperpc.fetch(string username, string password, string id, string format)

Description. Fetches a specific recipe, using an id returned by reciperpc.search() and specifying a format.

Parameters. The username and password parameters have the standard types and meanings.

The id parameter is a string containing an identifier returned by the reciperpc.search() method.

The format parameter is a string containing one of the format identifiers returned by the reciperpc.config() method.

Return value. The requested recipe in the requested format, encoded as base64-encoded binary in a base64 type.

Base64-encoded binary is a safe method of sending arbitrary binary data through channels that can only accept ASCII text. It's the usual way of sending Unicode or other special characters via email, for example. Most XML-RPC libraries do base64 encoding and decoding seamlessly, and many external libraries and tools exist for this as well.

Faults. The server may return these faults:

Fault code Fault description
401 Invalid username or password.
404 Invalid recipe identifier.
416 Invalid format.
5xx Implementation-specific faults.

Optional methods

Servers are strongly encouraged, but not required, to implement the introspection methods

system.listMethods()
system.methodSignature()
system.methodHelp()
These methods are described in the
XML-RPC for PHP documentation.

Servers and clients may implement boxcarring, a technique for sending or receiving multiple requests using the method

array system.multicall(array calls)
However, be forewarned that this technique is not supported by many XML-RPC implementations. This method is not implemented in the reference implementation.

Servers and clients may also implement this method:

boolean submit(base64 recipe, string format)
This submits a recipe in the specified format for inclusion in the server's recipe repository. The server returns true if it was able to parse the recipe and false or a fault if there was an error (such as a formatting error). Note that a true response does not indicate that the recipe has been added to the repository - most servers accepting submissions will probably want to include some human review of submissions for security, so the client should expect a delay before seeing the recipe available for download.

Odds and ends

The meaning of criterion values. A criterion is normally the name of a recipe attribute, such as "name" or "ingredient", and so when you specify a string value for the criterion in the reciperpc.search() method, the server typically fetches recipes whose attribute contains that string (searching case-insensitively): hence in the example we match any recipe whose name contains "spaghetti" (searching case-insensitively).

However, the server is free to behave differently. For instance, it may search for exact matches only. Or it may interpret the value as a number and search for values greater or less than the given one. Or it may require a format, such as a-b for a range from one number a to another b. In any of these cases, the server should (but is not required to) provide and document implementation-specific fault codes (integers > 100) and detailed, helpful fault messages for invalid criterion values.

Fault descriptions. This protocol only prescribes the fault codes and their meanings; a server may return any fault string that preserves the meaning. For instance, a server may return a fault string describing the fault in a different natural language, such as German.

Order of method calls. The normal order of method calls is shown in the example above, although a real session might include multiple calls to reciperpc.search() (if the server does not return all matching recipes the first time) and multiple calls to reciperpc.fetch() (if more than one recipe is desired). However, clients are free to call any method at any time; for instance, if the identifier is known, the client can simply issue the reciperpc.fetch() call immediately.

Earlier versions

For historical interest, earlier versions of this document are archived here.

RecipeRPC specification version 0.1
RecipeRPC specification version 0.2
RecipeRPC specification version 0.3

Copyright and disclaimer

Copyright 2004 Douglas Squirrel.

This document and translations of it may be copied and furnished to others, but not modified except as described in the next paragraph.

Derviative works of any kind whatsoever, including modified versions of this document or explanations or paraphrases of it, may be created and used in any way, so long as the word RecipeRPC is not used to identify any protocol materially different from the one described in this document. For example, you can document your own protocol based on RecipeRPC and use parts of this document in the description of your new protocol, but you can't refer to your new protocol as RecipeRPC.

While these copyright restrictions apply to the written RecipeRPC specification, no claim of ownership is made to the protocol it describes. Any party may, for commercial or non-commercial purposes, implement this protocol or any variation on it without royalty or license fee. The limited permissions granted herein are perpetual and will not be revoked.

This document and the information contained herein is provided on an "AS IS" basis and THE AUTHOR DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.


Last updated 17 February 2004
This web site copyright 2004 D. Squirrel
Graphics provided by Jeff Bucchino,
the Wizard of Draws, for noncommercial use.
SourceForge.net Logo