Signup fields via the REST API

With the purpose of adding parity between the web version and the REST API, we are introducing a minor breaking change in the next version of BuddyPress (v14.0.0 ) in how the BuddyPress REST API handles Signup XProfile fields.

In this article, I’ll try to explain what the change is, why is necessary, and how you can prepare your app for these changes which will be available when the new BuddyPress version is released.

What problem are we solving?

Currently, our REST API does not support getting Signup XProfile fields or saving them. This means that when creating a signup via the API, there is only one XProfile field available, the user_name argument. This argument is mapped to the required “Name (Primary)” field.

However, if a community administrator creates more custom Signup fields, they would not be able to use them via the REST API. This creates an incomplete experience for API consumers that need to have signup fields in their apps.

As part of the, not yet released, v14.0.0 version, we are changing this behavior. API consumers will be able to return the Signup XProfile fields, and send them while creating a signup via the API. 🥳

Fetch Signup fields

To fetch signup fields only, we introduced a new argument, signup_fields_only. Here is an example of a request to select the Signup group, using the XProfile Groups endpoint:

bp.apiRequest( {
  path: 'buddypress/v1/xprofile/groups',
  type: 'GET',
  data: {
    context: 'view',
    fetch_fields: true // <-- required, in this endpoint.
    signup_fields_only: true // <--- new argument.
  }
} ).done( function( data ) {
  return data; // <--- It returns the signup fields only.
} ).fail( function( error ) {
  return error;
} );

Here is an example of a request to select only the Signup fields, using the XProfile Fields endpoint:

bp.apiRequest( {
  path: 'buddypress/v1/xprofile/fields',
  type: 'GET',
  data: {
    context: 'view',
    signup_fields_only: true // <--- new argument.
  }
} ).done( function( data ) {
  return data; // <--- It returns the signup fields only.
} ).fail( function( error ) {
  return error;
} );

Send signup fields

While creating a signup via the API, a new argument, signup_field_data is required. This argument is mapped to the Signup fields (the order the field data is sent is not important).

bp.apiRequest( {
  path: 'buddypress/v1/signup',
  type: 'POST',
  data: {
    context: 'edit',
    user_login: 'testuser',
    user_email: 'test@user.mail',
    password: 'password' // Always use strong passwords, not like this one!
    "signup_field_data[0][field_id]": "36",
	"signup_field_data[0][value]": "Arabic, English",
	"signup_field_data[1][field_id]": "31",
	"signup_field_data[1][value]": "Sometimes, I never travel",
	"signup_field_data[2][field_id]": "35",
	"signup_field_data[2][value]": "This is some text for my profile.",
	"signup_field_data[3][field_id]": "1",
	"signup_field_data[3][value]": "New Profile",
	"signup_field_data[4][field_id]": "19",
	"signup_field_data[4][value]": "Option 01, Option 03",
  }
} ).done( function( data ) {
  return data;
} ).fail( function( error ) {
  return error;
} );

The most noticeable change is that required fields will be respected in the API now. If you send a request creating a signup without the required fields (or sending empty values for the required fields), the REST API will complain about it, just like the web version.

Here is an example of a failed request without a required field.

{
  "code": "bp_rest_signup_field_required",
  "data": {
    "status": 500
  },
  "message": "The CUSTOM field is required."
}

How to migrate

Now, how can you prepare for this change? If your project makes use of the now deprecated user_name argument, you’ll need to update your app to use the new signup_field_data argument when creating a signup via the REST API.

We haven’t updated our documentation yet with those changes, but here is the schema for the new argument:

"signup_field_data": {
  "description": "The XProfile field data for the new user.",
  "items": {
    "properties": {
      "field_id": {
        "description": "The XProfile field ID.",
        "required": true,
        "type": "integer",
      },
      "value": {
        "default": "",
        "description": "The value(s) (comma separated list of values needs to be used in case of multiple values) for the field data.",
        "required": true,
        "type": "string",
      },
      "visibility": {
        "default": "public",
        "description": "The visibility for the XProfile field.",
        "enum": [
          "public",
          "adminsonly",
          "loggedin",
          "friends"
        ],
        "required": false,
        "type": "string",
      }
    },
    "type": "object"
  },
}

The new field expects an array of data with the field_id, its value, and the visibility of the field.

Why do I need to move my code into the new signup_field_data?

One important goal of this change is to add parity with the web version. Keeping the new and the old argument user_name would defeat this purpose. It would also create unnecessary handling of fallbacks, and ultimately confusion.

A user could send the “Name (Primary)” field via user_name argument or using the new signup_field_data argument. Required fields would also not be truly required. Essentially, creating a lot of code to account for both situations.

It’s also accurate to say that the old behavior is a bug, not a feature (or at the very least an MVP of an MVP of an MVP). We are correcting this bug as part of this change.

=D

#developers, #rest-api