First of all, don’t expect much of this blog post. It’s intended to capture some thoughts and opinions I’ve noted down while working on my first real-world React / WP REST API application. It’s not intended to be polished, professional-grade marketing copy. It also assumes you have some familiarity with React, Redux, and the WP REST API — if you don’t, the blog post may not make sense. You’ve been warned.

I pretty much love React at this point, and can’t imagine using WordPress’ theming for anything in the future. If you hire me to build a brochure website, I will probably build it in React, just because.

What I like most is that everything is so damn elegant. The component-based architecture encourages you to think about whatever you’re building in terms of reusable pieces. I suspect this naturally lends itself to Better Quality Code.

But, React is also a substantial departure from WordPress’ quick and dirty ethos. A concern of mine is long-term maintainability of a React-based website, particularly for clients who think they’re getting a WordPress website and expect to be able to hire a WordPress developer for future changes to it.

Routing is painful. I haven’t found an elegant solution to the fact that routes need to be declared in WordPress and in React.

For the project I’m on, all routes are going into React first so the application works as expected. At some point, I’ll need to figure out how equivalent routes should be sustainably registered as WordPress rewrites.

The theory is that single page applications deployed as WordPress themes can use WordPress to serve response headers, social / SEO meta, and prepare an initial payload of data using the main query, before passing on the torch to React. In practice, I’ve worked very little of this out yet.

Or, I can noop WordPress’ route handling entirely, but then I’ll lose some of the benefit of having WordPress serving the initial pageload.

Which brings me to managing application state. Once you get over the day of effort to understand how Redux works, it’s really quite elegant. It also takes about 50% more effort than I’d like to get my application data into my components.

If I may make one request, could someone please write a redux-wp library to magically generate actions and reducers from my WP REST API index?

If you’re curious what real-world WP REST API endpoint registration looks like, here’s the Controller for a Record which, in the LMS data model of students completing activities and quizzes, stores the data of a student’s answers to an activity or quiz.

Commentary on my code, in no particular order, includes:

  • I’m not sure why I’m using register_rest_field() when I’m already subclassing and have access to the schema. I should probably refactor that.
  • Make sure to register your fields before your routes, if you’re using the helpers to transform schema into route args. This bit me once.
  • While it’s nice I can use a filter to modify the behavior of WP_REST_Posts_Controller->get_items(), aforementioned method is impossible to subclass.
  • The REST API’s concept of context (e.g. embed vs. view vs. edit) is mostly useless in my case, because I’m always fetching the entirety of the resource. I would like for a way to easy disable the concept of context. Also, we should’ve gone with title and title_rendered instead of creating a title object on the Post resource.
  • Using arg_options always feels really awkward, because registering a schema property seems like it should be equivalent to registering a query parameter or anything else. I want to be able to use validate_callback, default, and others as top-level arguments to registering a schema property.

Generally, I consider the WP REST API controllers to be good, but not great, right now. I’m writing lots of tests for cases I don’t think I should need to write tests for, because the WP REST API is a bit leaky. For instance, I’d expect for my declaration of query params and schema to be the canonical truth of what the endpoint supports, which isn’t the case currently (e.g. you can deregister the password field on a Post-derived resource, and password will still be included in the response object).

In my ideal world, to create a custom post type endpoint, I would:

  • Extend WP_REST_Posts_Controller.
  • Define the shape of my resource (e.g. its schema)
  • Declare which operations the resource supports (list, get, create, update, delete) through some means where I didn’t have to extend register_routes()
  • Declare which query params the resource supports.
  • Implement permissions checks as needed.

Leave me any questions you have in the comments! Or, better yet, write about the real-world lessons you’ve learned.


      1. Yeah, all state is handled by react-redux so your components rely solely on props.

        Your components become a single function and you leverage functional programming patterns for composing them.

        Not to say there’s anything wrong/inferior about using PORC (plane old React components). I’m just finding the functional pattern provided by stateless components to be really enjoyable and simpler to reason about.

        All of the examples in the react-redux docs use this pattern:

Hand Built is Daniel Bachhuber, an effective developer with technology leadership you can trust.

How can I help?

Hit me at [email protected] with a short note about what you'd like to do.

My roots are WordPress and publishing, and I love pretty much everything related to web development (architecture, performance, security, etc.). When not working with clients, I also maintain WP-CLI (WordPress' command line interface) and other open source projects.

Want to connect? I'm on Twitter, Github and LinkedIn. Or, sign up for my TinyLetter for periodic newsletters.