Correct use of pipeline when consuming a REST API

I’m adding pipeline support to a module which consumes a REST API, providing parent and student records from a school admissions system. My work is mostly cobbled together from watching Don Jones toolmaking series on YouTube, and snippets from around the web, and I would appreciate input from anybody familiar with this type of design pattern.

The module has private functions to handle OAuth and generic API requests via a wrapper function for Invoke-RestMethod. Public functions expose each endpoint, e.g. Get-OAStudent for /students, Get-OAParent for /parents and so on. In turn, each endpoint supports /xxx/id to retrieve a single record. For example, Get-OAParent has 2 parameter sets, reflecting /parents/id (single record) and /parents (multiple records). For /parents/id, the id parameter is supplied as below, ideally accepting an array of IDs via the pipeline:


The wrapper function Invoke-OAAPIResquest is then called within the PROCESS{} block, to support pipeline input:

foreach($i in $ID){
$RESTParams['Resource'] = "parents/$i"
$Data = Invoke-OAAPIRequest @RESTParams -ErrorAction Stop
Write-Warning "Failed to retrieve ID $i. $($_.Exception.Message)"
$Parent = $Data.parent
Write-Output $Parent

My question(s): Should the $Parent object(s) be output individually as above, or in the END{} block as an array? Should it be turned into a PSCustomObject first? Any design / best practice / performance reasons?


Unless the API let me pass multiple ids in the body vs a standard REST parents (return all) or parents/123 (by id), I would do it like this:

function Get-OAParent {
    param (
    begin {}
    process {
        $RESTParams ['Resource'] = 'parents'

        if ($PSBoundParameters.ContainsKey) {
            $RESTParams ['Resource'] = ('parents\{0}' -f $Id)

            $Data = Invoke-OAAPIRequest @RESTParams -ErrorAction Stop
            Write-Warning "Failed to retrieve ID $i. $($_.Exception.Message)"
    end {$Data.parent}

The api can return all or by reference id, so I would write my function like that. Not sure if there are a ton of items in parents, but if I wanted 10 parents in my code later, I would do something like:

$parentIds = 123,212.566,568
$allParents = Get-OAParent
$allparents | Where{$parentIds -contains $_.Id}

The only time I’ve had to loop is if /parents returns a small object like and parent.Name and parent/123 returns a larger object with details. I would add a switch like -Small to return just the id\name, otherwise, I would loop and get the details as I need them for the other functions.