What’s the correct way to add capabilites to user roles?

The best place to add this would be in the plugin’s activation hook. You can either call the dynamic activate_{$plugin} hook, or better yet use the provided register_activation_hook method.

Using your code example above – something like this would be what you’re looking for:

register_activation_hook( __FILE__, function() {
    $role = get_role( 'editor' ); 
    $role->add_cap( 'edit_booked_appointments', true );
} );

It’s also important to clean up after your plugin deactivates by registering a deactivation hook to clean up any DB changes you’ve made:

register_deactivation_hook( __FILE__, function() {
    $role = get_role( 'editor' ); 
    $role->remove_cap( 'edit_booked_appointments', true );
} );

Note: These code examples are being used in the main plugin file. If you’re using it outside of that context, you’ll need to provide the main plugin file instead of the magic __FILE__.