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
struct
s:
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.htmlwe 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 string
s 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 string s |
Names of the formats available from this server. Examples: RecipeML, MealMaster. |
The criteria
element of this struct
is itself a
struct
, in which:
string
giving the name of a
search criterion recognised by the server; andarray
, which is
either a list of two or more valid values for the named criterion,
or a 1-element array, the latter meaning that any value is
acceptable for the criterion.[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:
string
s from the list of criteria
names provided by the reciperpc.config()
method; andstring
s, each of
which provides a value for its corresponding key.
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 struct
s 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.