PHP Iterator classes - php

I'm trying to figure out what's the actual benefit of using Iterator classes in Object Oriented PHP over the standard array.
I'm planning to upgrade my framework by converting all arrays to object, but I just don't understand the actual need apart from having the system being fully OOP.
I know that by the use of IteratorAggregate I can create:
class MyModel implements IteratorAggregate {
public $records = array();
public function __construct(array $records) {
$this->records = $records;
}
public function getIterator() {
return new ArrayIterator($this->records);
}
}
and then simply loop through it like using the array:
$mdlMy = new MyModel(array(
array('first_name' => 'Mark', 'last_name' => 'Smith'),
array('first_name' => 'John', 'last_name' => 'Simpson')
));
foreach($mdlMy as $row) {
echo $row['first_name'];
echo $row['last_name'];
}
Could someone in simple terms explain the actual purpose of these - perhaps with some use case.

Shortest Answer
Extensibility & abstraction.
Abstract Answer
As soon as you have the ArrayAccess interface, you've got things that aren't arrays but have an array interface. How will you traverse these? You could do it directly, which is where the Iterator interface comes from. Iterator might not make sense for some classes, either due to the single-responsibility principle, or for performance's sake, which is where you get IteratorAggregate.
SPL-based Answer
SPL introduced a number of data structures. Iterators allow these to be traversed in foreach loops. Without iterators, collections would need to be converted to arrays, a potentially costly operation.
Long Answer
Source-Iterators
The first use comes up with data sources (e.g. collections), which aren't all natively held in arrays. Examples (note: there is some overlap):
trees
the file system
the previously mentioned SPL data structures
network communications
database query results
external process results
ongoing computation (PHP 5.5 introduces generators for this case)
Any collection that isn't array-based typically either is an iterator or has a corresponding iterator. Without iterators, each of the above would need to be converted to or collected in an array, which might incur heavy time & space costs. If you only had arrays available for iteration, the process can't proceed until the conversion/collection finishes. Iterators allow for partial results to be processed as they become available, and for only portions of collections to be in memory at any point in time.
In particular case outlined in the question, the UserEntityManager::getAll() method could benefit from an Iterator by reducing memory usage. Depending on what is used for data storage, an Iterator will allow just some user records to be processed at a time, rather than loading all at once.
ArrayIterator, DirectoryIterator, and the SPL data structures are all examples of source-iterators (i.e. they iterate over a data source).
Processing-Iterators
Another use for iterators is in-place data processing. Processing iterators wrap other iterators, which allows for iterator composition. In PHP, these are the OuterIterators and sometimes have 'IteratorIterator' in their names.
You might ask "Why not just use functions?" The answer is that you could, but iterator composition (like function composition) is another (powerful) tool that allows for different types of solutions, sometimes achieving better performance or clarity. In particular, functions become a choke point in PHP, since it doesn't have in-language concurrency. Functions must finish before returning a result, which can be costly in terms of time & space, just as using arrays for iteration can be costly. Shallow.
The choke-point could be side-stepped by returning an iterator from a function, but that places a function call in between each iterator. Iterator composition allows deep iterator-based computations, cutting out the middle-man.
As for use-cases, consider a batch processing system that consumes data from multiple feeds, all of which have different formats. An adapting iterator can normalize the data for processing, allowing a single batch processor to service all the feeds.
As a reality check, in PHP you typically don't go full iterator-style any more than you'd write full-FP style, though PHP supports it. You usually don't compose more than a few iterators at a time (just as you often don't compose more than a few functions at a time in languages with function composition), and you don't create numerous iterators instead of functions.
RecursiveIteratorIterator is an example of a processing iterator; it linearizes a tree (simplifying tree traversal).
Iterator & Functional Styles
Iterator composition allows for a style closer to functional programming. At its most basic, an iterator is (roughly) a sequence. In FP, the most basic operation is fold (aka reduce), though others (especially append/concat, filter and map) are often implemented natively rather than in terms of fold for performance. PHP supports a few sequence operations on iterators (usually as OuterIterators); many are missing, but are easy to implement.
append: AppendIterator
cons: nothing, but easily (though not efficiently) implemented by creating an iterator that takes a single value, converting it to a single-element sequence, along with AppendIterator. EmptyIterator represents the empty sequence.
filter: CallbackFilterIterator
convolute (aka zip): MultipleIterator
slice: LimitIterator
map - nothing, but easily implemented
fold: nothing. Using a foreach loop and accumulating a value in a variable is probably clearer than implementing fold, but if you find a reason to do so, it's also straightforward (though probably not as an iterator).
flat-map: nothing. Can be written fairly easily (though not efficiently) in terms of append and map.
cycle: InfiniteIterator
unfold: generators (which are, in general, just a special case of iterators).
memoization: CachingIterator. Not so much a sequence operation as an (FP language) feature for function results.
The Future
Part of any language design is considering what the language could be. If concurrency were ever added to PHP, code that uses iterators (especially processing-iterators) could be made concurrent without being changed by making the iterators themselves concurrent.

Like this you have no advantage. Yet. But as soon as you need to implement some new functionality, you are having fun!
If you want to add a record to your 'array', but need to do some checking first, you'll have that in all instances: you don't have to find all the places you use this array, but you'll just add your validation to the constructor.
All other things that could go in a model will be your advantage.
But beware, 'OOP' is not "I'm using objects me!". It is also about what objects you have, what they do, etc. So don't just go packing all your arrays in objects and call it "going fully OOP". There's nothing OOP about that, nor is there a limit on using arrays in an OOP project.

Related

PHP using objects instead of arrays

When I started to learn OOP programming I read that everything is an object. For the most time I develop in PHP. Arrays have important role here. In languages like C# in most cases you really have to use and pass objects not arrays.
For example:
Class Product
{
private $data = array();
public function __construct()
{
$this->data['setting_1'] = 'a';
$this->data['setting_2'] = 'b';
$this->data['setting_3'] = 'c';
$this->data['setting_4'] = 'd';
$this->data['setting_5'] = 'e';
}
}
Is there any sense to create classes for everything when you use PHP? For example:
Class Product
{
private $setting_1, $setting_2, $setting_3, $setting_4, $setting_5;
}
And then instantiate class Product in another class (eg. Model) and return object instead of array (eg. to Controller)?
The answer is simple.
Everything is an object
is just an ideal.
In most real world OOP languages there are simple data types as well. Even in Java or CSharp. In PHP there is even an array as a complex, non object data type. You should not worry using it, also in OOP context of course.
Note that having the powerful array data type is more an advantage than a disadvantage. In my opinion the most lacking OOP feature of PHP is polymorphism, btw.
However, PHP5 introduced a suite of iterators and data structures, in the so called Standard PHP Library (SPL) extension, which is part of the PHP core distribution. You can have a look at them, but in most cases the array data type should work well (and performant).
No. Not everything needs to be in a class. This isn't Java. :P
PHP is a multi-paradigm language. That means it's perfectly legitimate to use some OO without going whole-hog. The OOP wonks might tell you how horrible a person you are, but OOP is only worthwhile when it reduces overall complexity. Wrapping every value up in a class, for the sake of doing it, adds complexity for no real gain.
A class is basically a template for data that has some unique behavior of its own. If your data doesn't need behavior associated with it (special construction, validation, interpretation, or persistence, for example), wrapping it up in objects is often overkill.
In the "everything is an object" mindset, keep in mind this applies to languages that were OO based from day 1. PHP is not one of those languages, objects were added after the fact. So your simple variable types in PHP are not objects, they are smaller & simpler pieces of memory.
It's splitting hairs, but if you don't need to use an object in PHP, then don't, simple arrays are lighter than objects that contain an array. By lighter I mean they use less ram, and in turn, run slightly faster.
The best advice you can get about writing PHP is KISS (Keep It Simple Stupid).
Answering "Is there any sense to create classes for everything when you use PHP?" as "Is there any sense to create properties in classes for everything when you use PHP?"
Yes, it is very difficult to develop on someone else's code when all that was used was arrays. Specially if there are no constants making it very possible to mistype something to create a bug which would be extremely hard to find.
Also, not that you are not talking about "creating objects for everything" but properties vs a list (array) of values, which is what I based my answer on.

Associative Array versus SplObjectStorage

I'm working on code to manage a collection of unique objects. The first prototype of this code utilises an associative array, basically as that's the way I've always done it.
However, I'm also keen on taking advantage of functionality that's been added to more modern versions of PHP such as [SplObjectStorage][1] for doing this instead, partly as a learning experience, partly because it's bound to offer advantages (benchmarks I've seen suggest that SplObjectStorage can be faster than arrays in a lot of cases).
The current implementation has an associative array that I check with in_array() to see if an object is already in the array before adding a new object to it.
The big problem I can see with SplObjectStorage is that it doesn't seem (at first glance) to support key/value associative array behaviour, and can only be treated as an indexed array. However, the documentation for the newer features of PHP isn't up to the standards of the documentation of more established parts of the language and I might simply be missing something.
Can I use SplObjectStorage in place of an associative array? If so, how do I define the key when adding a new object? More importantly, what are the relative advantages and disadvantages of SplObjectStorage when compared to associative arrays?
You shouldn't see the SplObjectStorage as a key-value store, but merely a set of objects. Something is in the set or not, but its position is not important.
The "key" of an element in the SplObjectStorage is in fact the hash of the object. It makes it that it is not possible to add multiple copies of the same object instance to an SplObjectStorage, so you don't have to check if a copy already exists before adding.
However, in PHP 5.4 there is a new method called getHash() which you can override that will return the "hash" of the object. This - in a sense - returns/set the key so you can allow it to store under different conditions.
The main advantage of SplObjectStorage is the fact that you gain lots of methods for dealing and interacting with different sets (contains(), removeAll(), removeAllExcept() etc). Its speed is marginally better, but the memory usage is worse than normal PHP arrays.
Results after running this benchmark with 10,000 iterations on PHP 5.6.13:
Type
Time to fill
Time to check
Memory
SplObjectStorage
0.021285057068
0.019490000000
2131984
Array
0.021125078201
0.020912000000
1411440
Arrays use 34% less memory and are about the same speed as SplObjectStorage.
Results with PHP 7.4.27:
Type
Time to fill
Time to check
Memory
SplObjectStorage
0.019295692444
0.016039848328
848384
Array
0.024008750916
0.022011756897
3215416
Arrays use 3.8 times more memory and are 24% slower than SplObjectStorage.
Results with PHP 8.1.1:
Type
Time to fill
Time to check
Memory
SplObjectStorage
0.009704589844
0.003775596619
768384
Array
0.014604568481
0.012760162354
3215416
Arrays use 4.2 times more memory and are 50% slower than SplObjectStorage.
When all the memory allocated to array is used up, the memory allocated to it will be doubled. In this context, a collection of objects may be more effective structure.

OOP : One class for database table, one class for database table row

Currently, I build two classes for each database table. For instance, if I have the table person, I will have the classes Person_List and Person.
Design-wise, is it better
for Person_List to output an array of Person; or
for it to output an array containing arrays of rows in the table.
Performance-wise, which is better?
I believe that design-wise, and taking performance into account, would be to (if you insist on Person_List class to represent table and Person to represent single record):
use Iterator interface for Person_List class, so you can iterate through the table without the need to pull all the records at once (it should be significant performance gain in some cases),
additionally use Countable interface for Person_List class, so you are able to count all the results if necessary by getting count directly from database,
This should give you flexibility and allow you to use Person_List class objects similarly as arrays.
If you still have problems employing these two interfaces, here is some explanation:
every time you do foreach ($table as $record) (where $table is an instance of Person_List), the current() method of Person_List class will be invoked (because it is a part of Iterator interface - see docs here), which should return an object of Person class; this should happen using eg. mysql_fetch_object();
when you call count($table) (where $table is an instance of Person_List), the count() method of Person_List class will be invoked, which in turn can use eg. mysql_num_rows() function to return all the results instead of pulling them from database and then counting (this will be again significant performance gain),
It really depends on what you are doing with the records. Accessing columns on the records shouldn't be much (any?) faster to use arrays. Not enough to justify not using objects
Arrays are lighter (smaller in memory, especially) than objects, but if you use Iterator like #Tadeck mentions, this shouldn't be an issue, as you'd only have one instance in memory at a time.
In summary, objects are almost always a better design (from an interface standpoint), however, if you are not sure from a performance standpoint, benchmark the candidate implementations. If the difference isn't noticeable enough, use objects.
You tagged this OOP so I guess you want to work with objects. In that case you'd want to have it return PersonRow objects, e.g. objects that represent a row in the db table. Have a look at
RowData Gateway Pattern
description of the Row Data Gateway Pattern
You should not worry about performance. Come up with a solid design that is readable and maintainable. Only bother about performance when you put your design into action, profiled it and found it doesnt meet performance requirements.

Implementing a memory-efficient arrayAccess class in PHP

I am creating a class that implements the composite pattern; the class is supposed to be able to represent a tree (so let's call it Tree).
In order to use as little memory as possible, when a Tree class instance is passed an array, it is kept as an array until the index is required; at which time a new child Tree instance is created and returned
The reasoning for this: My Tree instances pass through many filters and their content might be traversed and modified by many observers, but their content will be requested only once (on the final rendering). Moreover, a certain chunk might not be rendered at all, so it would be wasted memory to create instances of Tree that are not even going to be used.
In other words, if one uses
$class->set($array,$index); //(or $class[$index] = $array)
, the array is stored as normal. But when someone uses
$class->get($index) //(or $class[$index])
, a new instance of Tree will be returned (and cached for subsequent calls).
However, I am left with a dilemma: Do I
create a new instance of Tree when someone sets data?
Pros: code is easy to write, easy to maintain, easy for someone to pick up and improve upon
Cons: memory consumption, even more if we consider a part of the data entered might not be used. Manipulation gets more messy as special methods have to be written for special cases (as opposed to dealing with native arrays).
leave it as is, but have people do $class[$index] = array($index2=>$array)?
Pros: everything stays stored as an array, so normal array functions work, and memory consumption is
minimal.
cons: the usage is less "elegant", and possibly more complex.
I know this is not a forum, so I am not asking for opinions, but for the advice of someone having already developed a (potentially heavy) tree structure in PHP and what is the best way (or "accepted way") to go about it.
Demo creating the Tree on construct and Demo creating Tree on demand are simple tests you can run for yourself.
The latter creates new node objects only when they're accessed, thus the memory consumption is not that high.
The beauty of object oriented programming, encapsulation and facades is that nobody cares what you do internally, as long as the API does what it's supposed to. Whoever / Whatever is using your TreeNode doesn't need to know how it functions internally. Just go with whatever feels right. Design your APIs right and you can change internals any time.

Why return object instead of array?

I do a lot of work in WordPress, and I've noticed that far more functions return objects than arrays. Database results are returned as objects unless you specifically ask for an array. Errors are returned as objects. Outside of WordPress, most APIs give you an object instead of an array.
My question is, why do they use objects instead of arrays? For the most part it doesn't matter too much, but in some cases I find objects harder to not only process but to wrap my head around. Is there a performance reason for using an object?
I'm a self-taught PHP programmer. I've got a liberal arts degree. So forgive me if I'm missing a fundamental aspect of computer science. ;)
These are the reasons why I prefer objects in general:
Objects not only contain data but also functionality.
Objects have (in most cases) a predefined structure. This is very useful for API design. Furthermore, you can set properties as public, protected, or private.
objects better fit object oriented development.
In most IDE's auto-completion only works for objects.
Here is something to read:
Object Vs. Array in PHP
PHP stdClass: Storing Data in an Object Instead of an Array
When should I use stdClass and when should I use an array in php5 oo code
PHP Objects vs Arrays
Mysql results in PHP - arrays or objects?
PHP objects vs arrays performance myth
A Set of Objects in PHP: Arrays vs. SplObjectStorage
Better Object-Oriented Arrays
This probably isn't something you are going to deeply understand until you have worked on a large software project for several years. Many fresh computer science majors will give you an answer with all the right words (encapsulation, functionality with data, and maintainability) but few will really understand why all that stuff is good to have.
Let's run through a few examples.
If arrays were returned, then either all of the values need to be computed up front or lots of little values need to be returned with which you can build the more complex values from.
Think about an API method that returns a list of WordPress posts. These posts all have authors, authors have names, e-mail address, maybe even profiles with their biographies.
If you are returning all of the posts in an array, you'll either have to limit yourself to returning an array of post IDs:
[233, 41, 204, 111]
or returning a massive array that looks something like:
[ title: 'somePost', body: 'blah blah', 'author': ['name': 'billy', 'email': 'bill#bill.com', 'profile': ['interests': ['interest1', 'interest2', ...], 'bio': 'info...']] ]
[id: '2', .....]]
The first case of returning a list of IDs isn't very helpful to you because then you need to make an API call for each ID in order to get some information about that post.
The second case will pull way more information than you need 90% of the time and be doing way more work (especially if any of those fields is very complicated to build).
An object on the other hand can provide you with access to all the information you need, but not have actually pulled that information yet. Determining the values of fields can be done lazily (that is, when the value is needed and not beforehand) when using an object.
Arrays expose more data and capabilities than intended
Go back to the example of the massive array being returned. Now someone may likely build an application that iterates over each value inside the post array and prints it. If the API is updated to add just one extra element to that post array then the application code is going to break since it will be printing some new field that it probably shouldn't. If the order of items in the post array returned by the API changes, that will break the application code as well. So returning an array creates all sorts of possible dependencies that an object would not create.
Functionality
An object can hold information inside of it that will allow it to provide useful functionality to you. A post object, for instance, could be smart enough to return the previous or next posts. An array couldn't ever do that for you.
Flexibility
All of the benefits of objects mentioned above help to create a more flexible system.
My question is, why do they use objects instead of arrays?
Probably two reasons:
WordPress is quite old
arrays are faster and take less memory in most cases
easier to serialize
Is there a performance reason for using an object?
No. But a lot of good other reasons, for example:
you may store logic in the objects (methods, closures, etc.)
you may force object structure using an interface
better autocompletion in IDE
you don't get notices for not undefined array keys
in the end, you may easily convert any object to array
OOP != AOP :)
(For example, in Ruby, everything is an object. PHP was procedural/scripting language previously.)
WordPress (and a fair amount of other PHP applications) use objects rather than arrays, for conceptual, rather than technical reasons.
An object (even if just an instance of stdClass) is a representation of one thing. In WordPress that might be a post, a comment, or a user. An array on the other hand is a collection of things. (For example, a list of posts.)
Historically, PHP hasn't had great object support so arrays became quite powerful early on. (For example, the ability to have arbitrary keys rather than just being zero-indexed.) With the object support available in PHP 5, developers now have a choice between using arrays or objects as key-value stores. Personally, I prefer the WordPress approach as I like the syntactic difference between 'entities' and 'collections' that objects and arrays provide.
My question is, why do they (Wordpress) use objects instead of arrays?
That's really a good question and not easy to answer. I can only assume that it's common in Wordpress to use stdClass objects because they're using a database class that by default returns records as a stdClass object. They got used to it (8 years and more) and that's it. I don't think there is much more thought behind the simple fact.
syntactic sugar for associative arrays
-- Zeev Suraski about the standard object since PHP 3
stdClass objects are not really better than arrays. They are pretty much the same. That's for some historical reasons of the language as well as stdClass objects are really limited and actually are only sort of value objects in a very basic sense.
stdClass objects store values for their members like an array does per entry. And that's it.
Only PHP freaks are able to create stdClass objects with private members. There is not much benefit - if any - doing so.
stdClass objects do not have any methods/functions. So no use of that in Wordpress.
Compared with array, there are far less helpful functions to deal with a list or semi-structured data.
However, if you're used to arrays, just cast:
$array = (array) $object;
And you can access the data previously being an object, as an array. Or you like it the other way round:
$object = (object) $array;
Which will only drop invalid member names, like numbers. So take a little care. But I think you get the big picture: There is not much difference as long as it is about arrays and objects of stdClass.
Related:
Converting to object PHP Manual
Reserved Classes PHP Manual
What is stdClass in PHP?
The code looks cooler that way
Objects pass by reference
Objects are more strong typed then arrays, hence lees pron to errors (or give you a meaningful error message when you try to use un-existing member)
All the IDEs today have auto-complete, so when working with defined objects, the IDE does a lot for you and speeds up things
Easilly encapsulate logic and data in the same box, where with arrays, you store the data in the array, and then use a set of different function to process it.
Inheritance, If you would have a similar array with almost but not similar functionality, you would have to duplicate more code then if you are to do it with objects
Probably some more reason I have thought about
Objects are much more powerful than arrays can be.
Each object as an instance of a class can have functions attached.
If you have data that need processing then you need a function that does the processing.
With an array you would have to call that function on that array and therefore associate the logic yourself to the data.
With an object this association is already done and you don't have to care about it any more.
Also you should consider the OO principle of information hiding. Not everything that comes back from or goes to the database should be directly accessible.
There are several reasons to return objects:
Writing $myObject->property requires fewer "overhead" characters than $myArray['element']
Object can return data and functionality; arrays can contain only data.
Enable chaining: $myobject->getData()->parseData()->toXML();
Easier coding: IDE autocompletion can provide method and property hints for object.
In terms of performance, arrays are often faster than objects. In addition to performance, there are several reasons to use arrays:
The the functionality provided by the array_*() family of functions can reduce the amount of coding necessary in some cases.
Operations such as count() and foreach() can be performed on arrays. Objects do not offer this (unless they implement Iterator or Countable).
It's usually not going to be because of performance reasons. Typically, objects cost more than arrays.
For a lot of APIs, it probably has to do with the objects providing other functionality besides being a storage mechanism. Otherwise, it's a matter of preference and there is really no benefit to returning an object vs an array.
An array is just an index of values. Whereas an object contains methods which can generate the result for you. Sure, sometimes you can access an objects values directly, but the "right way to do it" is to access an objects methods (a function operating on the values of that object).
$obj = new MyObject;
$obj->getName(); // this calls a method (function), so it can decide what to return based on conditions or other criteria
$array['name']; // this is just the string "name". there is no logic to it.
Sometimes you are accessing an objects variables directly, this is usually frowned upon, but it happens quite often still.
$obj->name; // accessing the string "name" ... not really different from an array in this case.
However, consider that the MyObject class doesn't have a variable called 'name', but instead has a first_name and last_name variable.
$obj->getName(); // this would return first_name and last_name joined.
$obj->name; // would fail...
$obj->first_name;
$obj->last_name; // would be accessing the variables of that object directly.
This is a very simple example, but you can see where this is going. A class provides a collection of variables and the functions which can operate on those variables all within a self-contained logical entity. An instance of that entity is called an object, and it introduces logic and dynamic results, which an array simply doesn't have.
Most of the time objects are just as fast, if not faster than arrays, in PHP there isn't a noticeable difference. the main reason is that objects are more powerful than arrays. Object orientated programming allows you to create objects and store not only data, but functionality in them, for example in PHP the MySQLi Class allows you to have a database object that you can manipulate using a host of inbuilt functions, rather than the procedural approach.
So the main reason is that OOP is an excellent paradigm. I wrote an article about why using OOP is a good idea, and explaining the concept, you can take a look here: http://tomsbigbox.com/an-introduction-to-oop/
As a minor plus you also type less to get data from an object - $test->data is better than $test['data'].
I'm unfamiliar with word press. A lot of answers here suggest that a strength of objects is there ability to contain functional code. When returning an object from a function/API call it shouldn't contain utility functions. Just properties.
The strength in returning objects is that whatever lies behind the API can change without breaking your code.
Example: You get an array of data with key/value pairs, key representing the DB column. If the DB column gets renamed your code will break.
Im running the next test in php 5.3.10 (windows) :
for ($i = 0; $i < 1000000; $i++) {
$x = array();
$x['a'] = 'a';
$x['b'] = 'b';
}
and
for ($i = 0; $i < 1000000; $i++) {
$x = new stdClass;
$x->a = 'a';
$x->b = 'b';
}
Copied from http://atomized.org/2009/02/really-damn-slow-a-look-at-php-objects/comment-page-1/#comment-186961
Calling the function for 10 concurrent users and 10 times (for to obtain an average) then
Arrays : 100%
Object : 214% – 216% (2 times slower).
AKA, Object it is still painful slow. OOP keeps the things tidy however it should be used carefully.
What Wordpress is applying?. Well, both solutions, is using objects, arrays and object & arrays, Class wpdb uses the later (and it is the heart of Wordpress).
It follows the boxing and unboxing principle of OOP. While languages such as Java and C# support this natively, PHP does not. However it can be accomplished, to some degree in PHP, just not eloquently as the language itself does not have constructs to support it. Having box types in PHP could help with chaining, keeping everything object oriented and allows for type hinting in method signatures. The downside is overhead and the fact that you now have extra checking to do using the “instanceof†construct. Having a type system is also a plus when using development tools that have intellisense or code assist like PDT. Rather than having to google/bing/yahoo for the method, it exists on the object, and you can use the tool to provide a drop down.
Although the points made about objects being more than just data are valid since they are usually data and behaviour there is at least one pattern mentioned in Martin Fowler's "Patterns of Enterprise Application Architecture" that applies to this type of cenario in which you're transfering data from one system (the application behind the API) and another (your application).
Its the Data Transfer Object - An object that carries data between processes in order to reduce the number of method calls.
So if the question is whether APIs should return a DTO or an array I would say that if the performance cost is negligible then you should choose the option that is more maintainable which I would argue is the DTO option... but of course you also have to consider the skills and culture of the team that is developing your system and the language or IDE support for each of the options.

Categories