5

I want to integrate a public API to a plugin that I develop.

The usual way other plugins integrate APIs is to define some functions that can be called by any theme or plugin.

However, I think this is a bad idea since it will cause errors when my API plugin is not active and I came up with the idea of using filters and actions for the API. Much like this:

// Get some user specific data from my plugin:
$data = false;
if ( apply_filters( 'mp:is-active' ) ) {
    $data = apply_filters( 'mp:get-user-data' );
}

// Add a private notification for a single user:
do_action( 'mp:send-notification', $user_id, $message );

The question is:

I have never seen this kind of API in other plugins yet, so is there a good reason not to use it (e.g. bad performance, etc)

Or do you think this is a good way to go?

5

Surely this approach has some benefits, but has also some issues.

It's not really easy to use

If the target of your plugin are WordPress developers, they will be very familiar with plugin API, but end users are not.

For a non-developer, something like:

$data = give_me_the_data();

It's easier to understand, remember and type than:

$data = apply_filters( 'give_me_the_data' );

If you look at some of the questions on this site, you can understand how much confusion there is regarding action and filters in WordPress among newbie and non developers.

The "typo" issue

As a person that makes a lot of typos, I know that they are frustrating. If you write a function with a typo, it throws an error and the user immediately recognizes the problem. A typo in an action name will make the API fail but it's pretty hard to recognize.

As example:

$data = apply_filters('mp:get-user-data'); // works

$data = apply_filters('mo:get-user-data'); // does not work, hard to find why

$data = mp_get_user_data(); // works

$data = mo_get_user_data(); // does not work and throws an error, immediately found

The global hell

Actions and filters are just global variables. If you use them to build your API, your code can be f***ed up by any single other line of code present in the system.

It means that a bug in any who-knows-which plugin can make your plugin fail for no apparent reason. And the reason is that is not your plugin to fail.

Example:

do_action( 'mp:send-notification', $user_id, $message );

// somewhere else
add_action( 'all', 'do_something_bad_that_makes_your_plugin_fail');

Moreover, anyone can use those hooks and even if it may bring a lot of flexibility to your API, it also introduces a lot of complexity.

For example, if you use objects as arguments, being objects passed by reference, it's possible they are modified before your callback runs.

Conclusion

These are all the reasons that come now into my mind, but maybe there are other reasons if this approach is not widely used.

For me, I would not use this approach, especially for the last point, but I can not say it is absolutely wrong in WordPress context.

So I don't want to strongly discourage you in using it, just suggesting to consider all the issues in advance, because once you publicly release an API, it's very hard to switch.

  • 2
    Wow, amazing answer! Very useful information, thanks – Philipp Apr 19 '15 at 12:39
6

Both approaches are not mutually exclusive. As @gmazzap said, don’t create a callback hell.

But you can provide an initial hook, so other developers don’t have to rely on the rather slow function_exists() checks.

Example

In your plugin, provide a hook that other developers can use to call your classes and functions safely.

add_action( 'wp_loaded', [new Your_Plugin_Bootstrap, 'setup' ], 0 );

class Your_Plugin_Bootstrap {

    public function setup() {

        // set up your data and the auto-loader, then:
        do_action( 'your_plugin_loaded' );
    }
}

Now a third-party developer can use that hook and proceed with "normal" PHP.

add_action( 'your_plugin_loaded', function() {

    // safely use your plugin's classes here.
});

We do that in MultilingualPress, and the feedback from other developers was very good so far. It is easy to understand, and you have to learn just one hook.

See also: How to create an API for my plugin?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.