\documentclass[pdf]{prosper}
\usepackage[toc,highlight,clifford,notes,hlsections]{HA-prosper}

\usepackage{svn}
\SVNdate $Date: 2007-09-19 11:19:34 +0200 (Wed, 19 Sep 2007) $

\title{The Craft of API Design}
\subtitle{}
\author{Clifford Wolf\\
\institution{ROCK Linux - \href{http://www.rocklinux.org/}{http://www.rocklinux.org/}}\\
\institution{Csync2 - \href{http://oss.linbit.com/csync2/}{http://oss.linbit.com/csync2/}}\\
\institution{STFL - \href{http://www.clifford.at/stfl/}{http://www.clifford.at/stfl/}}\\
\institution{SPL - \href{http://www.clifford.at/spl/}{http://www.clifford.at/spl/}}}

\DefaultTransition{Wipe}
\TitleSlideNav{FullScreen}
\NormalSlideNav{ShowBookmarks}
\LeftFoot{\href{http://www.clifford.at}{Clifford Wolf}, \today}
\RightFoot{\href{http://www.clifford.at/}{http://www.clifford.at/}}

\begin{document}

\maketitle

% ============================================================================

\tsectionandpart{Introduction}


\begin{slide}{What are APIs? (1/2)}
\begin{itemize}

\item APIs are the (programatical) face of any piece of programming work.

\vspace*{0.5cm}

\item This is not limited to libraries intended for a broad use.

\vspace*{0.5cm}

\item It also covers the internal APIs found in every non-trivial program.

\end{itemize}
\end{slide}


\begin{slide}{What are APIs? (2/2)}
\begin{itemize}

\item APIs can be seen as extensions to the functionality of a programming
language.

\vspace*{0.5cm}

\item A programming language comes with a very limited built-in vocabulary
(set of functions and keywords).

\vspace*{0.5cm}

\item Every program module extends this vocabulary using its API.

\end{itemize}
\end{slide}


\begin{slide}{Why are APIs so important?}
\begin{itemize}

\item Today's programming projects tend to become huge pretty fast.

\vspace*{0.5cm}

\item It is hard to fully understand a huge program. 
\item So projects are broken up into modules with the APIs connecting them.

\vspace*{0.5cm}

\item With this seperation, it enables the programmer to focus on one module
without the need of knowing the rest of the project inside out.

\vspace*{0.5cm}

\item This can't work out unless the APIs are stable and cleanly seperating the
modules from each other.

\end{itemize}
\end{slide}


\begin{slide}{Why is API-Design so important?}
\begin{itemize}

\item Projects tend to ``grow'' with the APIs happening instead of beeing
designed.

\vspace*{0.5cm}

\item A well designed API enables the programmer to change a module's internals
without the need for changing the API or other modules.

\vspace*{0.5cm}

\item So if the API is good, everything else can also be improved later in
the process.

\vspace*{0.5cm}

\item But changing an API is always complicated, especially if the API has
grown already a big user base.

\end{itemize}
\end{slide}

% ============================================================================

\tsectionandpart{APIs Everywhere}

\begin{slide}{Frameworks}
\begin{itemize}

\item Frameworks are getting more important than the programming languages they
are written for and in.
\item Example given:
\begin{itemize}
\item Ruby on Rails
\end{itemize}

\end{itemize}
\end{slide}


\begin{slide}{Standard APIs (1/2)}
\begin{itemize}

\item Some APIs are part of standards and independend of implementations.
\item Example given:
\begin{itemize}
\item Standard C Library
\item The POSIX system call layer
\item The Verilog PLI layer
\item The MPI API
\end{itemize}

\vspace*{1cm}

\item A thing to ponder: \\
Usually it takes a few hours to learn a new language, learning the standard
libraries API is the hard part.

\end{itemize}
\end{slide}


\begin{slide}{Standard APIs (2/2)}
\begin{itemize}

\item Some APIs are even independend of programming languages.
\item Example given:
\begin{itemize}
\item The DOM API
\end{itemize}

\vspace*{1cm}

\item Changing a standard API once it is published and in use is close to
impossible.

\end{itemize}
\end{slide}


\begin{slide}{Toolchain Libraries}
\begin{itemize}

\item Most of today's applications don't implement a single non-trivial
algorithm.

\vspace*{0.5cm}

\item Instead ready-to-use libraries are used.

\vspace*{0.5cm}

\item Example given:
\begin{itemize}
\item APIs to sort functions vs. sorting algorithms - \\
Which one is more important for the daily work of an application programmer?
\end{itemize}

\end{itemize}
\end{slide}


\begin{slide}{Program Modules}
\begin{itemize}

\item Today's software projects are usually split up in small modules.

\vspace*{0.5cm}

\item This is pimarily done to fight complexity.

\vspace*{0.5cm}

\item The whole effort is useless if the APIs between this modules aren't
well designed.

\end{itemize}
\end{slide}

% ============================================================================

\tsectionandpart{Some Guidelines}


\begin{slide}{Introduction (1/2)}
\begin{itemize}

\item I will present some Guidelines for API design.

\vspace*{0.5cm}

\item None of them is an absolute rule.

\vspace*{0.5cm}

\item But I believe they bring up some questions everyone designing an API
should worry about.

\vspace*{0.5cm}

\item Feedback is always welcome.

\end{itemize}
\end{slide}


\begin{slide}{Introduction (2/2)}
\begin{itemize}

\item The following rules and things to ponder might be useful:
\begin{itemize}
\item For designing new APIs
\item For cleaning up existing APIs
\item For judging others APIs
\end{itemize}

\vspace*{0.5cm}

\item Every minute cut in API design {\bf will} hit you hard later.

\end{itemize}
\end{slide}


\begin{slide}{Hard to use wrong (1/2)}
\begin{itemize}
\item An API must be hard to use wrong.
\vspace*{0.5cm}
\item This is different from easy to use right.
\end{itemize}
\end{slide}

\begin{slide}{Hard to use wrong (2/2)}

{\bf Good example:}
\vspace*{0.5cm}
\begin{verbatim}
char *get_current_dir_name(void);
\end{verbatim}
\vspace*{0.5cm}
Returns a {\bf malloced} string containing the absolute pathname of the current
working directory. (GNU extension)

\vspace*{1.5cm}

{\bf Bad example:}
\vspace*{0.5cm}
\begin{verbatim}
char *strncpy(char *dest, const char *src, size_t n);
\end{verbatim}
\vspace*{0.5cm}
If there is no null byte among the first n bytes of src,
the result will not be null-terminated.

\end{slide}


\begin{slide}{Be self-descriptive (1/2)}
\begin{itemize}
\item The name should indicate what it does.
\vspace*{0.5cm}
\item Use names for function parameters when the language provides them.
\vspace*{0.5cm}
\item The API should pass the "Telephone test".
\end{itemize}

\vspace*{1.0cm}

{\bf Good example:}
\vspace*{0.2cm}
\begin{verbatim}
egrep --recursive --exclude-dir .svn Copyright .
\end{verbatim}

\vspace*{0.5cm}

{\bf Bad example:}
\vspace*{0.2cm}
\begin{verbatim}
char *exclude_dir_vect[] = { ".svn", NULL };
fictional_egrep_function(0, 0, 1, 0, 0, NULL, NULL,
    exclude_dir_vect, NULL, NULL, "Copyright", ".");
\end{verbatim}

\end{slide}

\begin{slide}{Be self-descriptive (2/2)}

{\bf Good example:}
\vspace*{0.2cm}
\begin{verbatim}
if (strstr(haystack, "needle"))
    printf("Found a needle!\n");
\end{verbatim}

\vspace*{0.5cm}

{\bf Bad example:}
\vspace*{0.2cm}
\begin{verbatim}
print "Found a needle!\n" if haystack =~ /needle/;
\end{verbatim}

\vspace*{1.0cm}

{\bf Good example:}
\vspace*{0.2cm}
\begin{verbatim}
int on_exit(void (*function)(int , void *), void *arg);
\end{verbatim}

\vspace*{0.5cm}

{\bf Bad example:}
\vspace*{0.2cm}
\begin{verbatim}
sighandler_t signal(int signum, sighandler_t handler);
\end{verbatim}

\end{slide}


\begin{slide}{Hide something}

\begin{itemize}
\item An API must hide something.
\vspace*{0.5cm}
\item The inner workings of a module must not dictate the API.
\end{itemize}

\vspace*{1.0cm}

{\bf Good and bad example:}
\vspace*{0.2cm}
\begin{verbatim}
void qsort(void *base, size_t nmemb, size_t size,
    int(*compar)(const void *, const void *));
\end{verbatim}

\end{slide}


\begin{slide}{Don't overoptimize}

\begin{itemize}
\item Allow for changes in the algorithm.
\item This is where optimization happens!
\end{itemize}

\vspace*{1.0cm}

{\bf Common failure:}
\vspace*{0.2cm}
Trading a 'fast API' for less flexibility.

\vspace*{1.0cm}

{\bf Bad Example:}
\begin{verbatim}
void qsort(void *base, size_t nmemb, size_t size,
    int(*compar)(const void *, const void *));
\end{verbatim}
(A user context pointer should be passed thru to compare.)

\end{slide}


\begin{slide}{Support User Contexts}

\begin{itemize}
\item Always pass a void user context pointer to callback functions.
\item Global variables should never be used for this!
\end{itemize}

\vspace*{1.0cm}

\begin{itemize}
\item Always configure a library using some kind of context object.
\item Global variables should never be used for this!
\end{itemize}

\vspace*{1.0cm}

\begin{itemize}
\item Bad examples: qsort(), LibXML2
\item Good examples: epool, PCRE
\end{itemize}

\end{slide}


\begin{slide}{Be Pragmatic}

\begin{itemize}
\item Each module/function should do one thing well.
\end{itemize}

\vspace*{1.0cm}

{\bf Bad examples:}
\begin{itemize}
\item Using select() as nanosleep/usleep replacement. (4.2BSD)
\end{itemize}

\vspace*{1.0cm}

{\bf Good examples:}
\begin{itemize}
\item BSD socket API
\item Most POSIX System Calls
\end{itemize}

\end{slide}


\begin{slide}{Be Consistent}

\begin{itemize}
\item Stick to a metaphor for API names.
\vspace*{0.2cm}
\item Stick to a lexical naming scheme.
\vspace*{0.2cm}
\item Don't mix plural and singular in names.
\vspace*{0.2cm}
\item Always use the same name for the same thing.
\vspace*{0.2cm}
\item Avoid off-by-one confusions.
\end{itemize}

\end{slide}


\begin{slide}{Be Restrictive}
\begin{itemize}
\item Make a clear distinction between internal and external APIs.
\vspace*{0.2cm}
\item Use accessor functions to access data structures.
\vspace*{0.2cm}
\item Don't export struct internals when the user should only pass the
pointer.

\vspace*{1.0cm}

\item Everything that does not affect the API can be changed easily!
\end{itemize}
\end{slide}


\begin{slide}{Be Selective}
\begin{itemize}

\item Limit the API to an easy to overview set of functions, if possible.
\vspace*{0.2cm}
\item Good example: PCRE API

\vspace*{1.0cm}

\item Provide an easy-to-use API for the most common use case, if feasible.
\vspace*{0.2cm}
\item Good example: CURL API

\end{itemize}
\end{slide}


\begin{slide}{Free everything}
\begin{itemize}

\item Provide {\tt done()}, {\tt destroy()} or {\tt cleanup()} functions.

\vspace*{0.5cm}

\item Make sure that it is possible to free {\bf every} resource allocated by
your library.

\vspace*{0.5cm}

\item Use memory debuggers like {\tt valgrind} to verify your implementation.

\end{itemize}
\vspace*{1.0cm}

{\bf Bad example:} \\
The QT library

\end{slide}


\begin{slide}{Two-level-documentation}
\begin{itemize}

\item Provide at least two levels of documentation:
\begin{itemize}
\item The big picture / tutorial
\item Function, Class, etc. reference
\end{itemize}

\vspace*{1.0cm}

\item Tools like doxygen can only help with the latter one.

\vspace*{1.0cm}

\item Always assume that the reader of your documentation starts with zero
knowlegde of your API.

\vspace*{0.5cm}

\item Always start with describing the bigger context.

\end{itemize}
\end{slide}


\begin{slide}{Document the data layout}
\begin{itemize}

\item Data structures etc. are almost ever under-documented.

\vspace*{0.5cm}

\item But often understanding the data structures is the key element for
understanding an API.

\vspace*{0.5cm}

\item In good programs the data structure tends to dictate the imperative part
of the program, not the other way around.

\end{itemize}

\vspace*{1.0cm}

{\bf Bad example:} \\
man pages

\end{slide}


\begin{slide}{Stick to a freeing-paradigm}
\begin{itemize}

\item Always be clear who is supposed to free what resource.

\vspace*{1.0cm}

\item Make a decision for one paradigm and stick to it.

\vspace*{1.0cm}

\item Freeing resources is the boring part.

\vspace*{0.5cm}

\item Nevertheless it's one of the most critical aspects in API design.

\end{itemize}

\vspace*{1.5cm}

(Know your contracts!)

\end{slide}


\begin{slide}{Program defensively}
\begin{itemize}

\item Be liberal with what you acceppt.

\vspace*{0.5cm}

\item Be conservative with what you pass to the outside world.

\vspace*{0.5cm}

\item Check for the impossible case.

\vspace*{0.5cm}

\item Fail early when you have to fail.

\vspace*{0.5cm}

\item Leave all checks in the production code.

\end{itemize}
\end{slide}


\begin{slide}{Support many languages}
\begin{itemize}

\item Support as many programming languages as possible.

\vspace*{1.0cm}

\item Use the swig library to export a C/C++ API to the scripting world.

\vspace*{1.0cm}

\item Provide command line tools to make the API's functionality accessible
from an ordinary UNIX shell.

\vspace*{1.0cm}

\item Provide a thin C-wrapper for C++ libraries.

\vspace*{1.0cm}

\item Use MinGW or Cygwin to create a Win32 port of your library.

\end{itemize}
\end{slide}


\tsectionandpart{References}


\begin{slide}{Books}
\begin{itemize}

\item The Pragmatic Programmer \\
Hunt and Thomas (ISBN-13: 978-0-201-61622-4)

\vspace*{1.0cm}

\item The Mythical Man-Month \\
Brooks (ISBN-13: 978-0-201-83595-3)

\vspace*{1.0cm}

\item The Elements of Programming Style \\
Kerninghan and Plauger (ISBN: 0-07-034207-5)

\end{itemize}
\end{slide}


\begin{slide}{This Presentation}
\begin{itemize}

\item Clifford Wolf \\
{\tt http://www.clifford.at/}

\vspace*{0.5cm}

\item More Presentations \\
{\tt http://www.clifford.at/papers/}

\vspace*{0.5cm}

\item This Presentation \\
{\tt http://www.clifford.at/papers/2008/apidesign/}

\end{itemize}
\end{slide}

% ============================================================================

\end{document}

