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?

    2 Answers 2

    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.

    1
    • 2
      Wow, amazing answer! Very useful information, thanks
      – Philipp
      CommentedApr 19, 2015 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?

      Start asking to get answers

      Find the answer to your question by asking.

      Ask question

      Explore related questions

      See similar questions with these tags.