Data Object & Method Structure

By this point we know how to structure the URL and send for the data. Now we'll get into how the method on the back-end should be structured to receive and handle the request. Remember, as previously mentioned, if every method can work with and expect the same data structure, then it doesn't matter how you combine the methods, just like Legos. So first lets discuss the data object.


function createData() {
  // Some logic here...
  
  return $data_template = (object) array(
    "success" => true, // A bool always expected here and always starts off as true until a method fails.
    "statusMessage" => "A beneficial message for a developer", // A string is expected here.
    "payload" => (object) array(
      "post" => ['johndoe','eavVESLkSegmaslee2eaga42',15], // Here is where the post data that was received gets inserted.
      "luggage" => (object) array( // Luggage always contains the properties of all existing models. In this case we only have a "users" property.
        "users" => [] // Each property wraps all objects with an array since we can always possibly expect more than one.
      )
    )
  );
}

$data_one = createData();

echo $data_one->payload->post[0]; // will echo johndoe

Now for the methods. We previously talked about two categories in which this would work, GET and CHANGE methods.

  • GET Methods - Will always check the data.payload.post property for the data needed to make the request.
  • CHANGE Methods - Will always check the data.payload.luggage.{ModelType} property for the necessary data that needs to be changed or updated with what has been provided via data.payload.post.
  • Both GET & CHANGE Methods - Will always check the data.success status prior to proceeding. If false, the data object gets passed through without any alterations.

Lets take a look at the methods we'll be using, to get a better idea on how we should structure our methods.


class users {

  // Example of a GET Method
  public function get($data,$key) {

    if ($data->success) {
      $username = $data->payload->post[$key];

      // Use $username to get user data and add it to the user array within luggage.
      $fake_user_obj = (object) array(
        "id" => 1,
        "password" => "test123"
      );

      // Add object to user array.
      $data->payload->luggage->users[] = $fake_user_obj;

      return $data;
    } else {
      return $data;
    }
  }

  // Example of a CHANGE Method
  public function changePass($data,$key) {

    if ($data->success) {
      $new_user_pass = $data->payload->post[$key];

      // Use $new_user_pass to update the provided users within luggage->users.
      // Typically this would just be one user, but doesn't mean we won't ever need to update multiple users.
      foreach($data->payload->luggage->users as $user_object) {
        $user_id = $user_object->id;
        // Some logic to a sql query that updates user with $new_user_pass
        // Return new pass.
        $user_object->password = $new_user_pass;
      }

      return $data;
    } else {
      return $data;
    }
  }

  // Example of a GET Method
  public function friends($data,$key) {

    if ($data->success) {
      $user_id = $data->payload->post[$key];

      // Use $user_id to get list of user's friends that exist within the user object, and add it to the user array within luggage.
      $fake_user_obj = (object) array(
        "id" => $user_id,
        "password" => "test123",
        "friends" => array("Jane","Biv","Rob")
      );

      // Add object to user array.
      $data->payload->luggage->users[] = $fake_user_obj;

      return $data;
    } else {
      return $data;
    }
  }
}

Obviously these bare-bone simplified methods, but you can easily see how each method can function when grouped together. Now on how the call would be processed.


$users = new users;
$result1 = $users->changePass($users->get($data_one,0),1);
$result2 = $users->friends($data_two,2);

// print_r $result1
stdClass Object(
  [success] => 1
  [statusMessage] => A beneficial message for a developer
  [payload] => stdClass Object(
    [post] => Array(
      [0] => johndoe
      [1] => eavVESLkSegmaslee2eaga42
      [2] => 15
    )
    [luggage] => stdClass Object(
      [users] => Array(
        [0] => stdClass Object(
          [id] => 1
          [password] => eavVESLkSegmaslee2eaga42
        )
      )
    )
  )
)

// print_r $result2
stdClass Object(
  [success] => 1
  [statusMessage] => A beneficial message for a developer
  [payload] => stdClass Object(
    [post] => Array(
      [0] => johndoe
      [1] => eavVESLkSegmaslee2eaga42
      [2] => 15
    )
    [luggage] => stdClass Object(
      [users] => Array(
        [0] => stdClass Object(
          [id] => 15
          [password] => test123
          [friends] => Array(
            [0] => Jane
            [1] => Biv
            [2] => Rob
          )
        )
      )
    )
  )
)

Which can finally be return in a JSON object as the following.


[  
  {  
    "success":true,
    "statusMessage":"A beneficial message for a developer",
    "payload":{  
      "post":[  
        "johndoe",
        "eavVESLkSegmaslee2eaga42",
        15
      ],
      "luggage":{  
        "users":[  
            {  
              "id":1,
              "password":"eavVESLkSegmaslee2eaga42"
            }
        ]
      }
    }
  },
  {  
    "success":true,
    "statusMessage":"A beneficial message for a developer",
    "payload":{  
      "post":[  
        "johndoe",
        "eavVESLkSegmaslee2eaga42",
        15
      ],
      "luggage":{  
        "users":[  
          {  
            "id":15,
            "password":"test123",
            "friends":[  
                "Jane",
                "Biv",
                "Rob"
            ]
          }
        ]
      }
    }
  }
]

To conclude, this isn't fully tested yet and I plan on releasing an API on my Github account using this methodology. Feel free to contact me about your thoughts on my idea for a combo API. I would like to hear input from other fellow developers.