Come gestire molti argomenti in un wrapper API?

2

Sto scrivendo un wrapper API PHP per un'API di terze parti. Voglio rendere tutti i metodi coerenti, ma non sono sicuro di come gestire il numero di argomenti accettati da alcune rotte API. Una richiesta API accetta fino a 30 argomenti. Ovviamente, sarebbe ingombrante elencare ogni argomento come parametro sul metodo. Attualmente, lo sto scrivendo per accettare gli argomenti richiesti come parametri del metodo, mentre tutti quelli facoltativi sono accettati in una matrice "additionalOptions" finale.

public function sampleApiMethod($reqVal1, $reqVal2, $additionalOptions) {
    //Method Code
}

Sfortunatamente, ci sono richieste API che hanno solo argomenti opzionali. In questo caso, l'unico parametro è l'array di opzioni oppure il metodo ha parametri individuali per gli argomenti facoltativi. Quando si passa solo un array, il metodo è coerente con gli altri metodi, ma non è il più intuitivo. Con quest'ultima opzione, perdo la struttura coerente. Esiste una sorta di best practice o struttura per un wrapper API che dovrei seguire per provare ad avere un'esperienza di utilizzo coerente degli sviluppatori?

    
posta Dan 03.05.2013 - 01:52
fonte

2 risposte

3

Ci sono un paio di buoni modi per gestirlo e dipende in realtà dalle tue preferenze personali e dalla complessità dell'interfaccia API. Per un'interfaccia di complessità semplice aumenterei il numero di funzioni per essere solo le chiamate più specifiche a un determinato set di casi d'uso. Potresti essere fortunato e scoprire che se ci sono solo 10 azioni caso d'uso diverse in cui un attore potrebbe aver bisogno di combinazioni diverse di argomenti obbligatori e facoltativi, allora potresti creare solo dieci diverse funzioni per questo.

Questa potrebbe non essere la soluzione migliore, tuttavia se ci sono una grande combinazione di argomenti e casi d'uso da considerare.

Dai un'occhiata al Pattern Builder

La premessa del modello Builder è che la classe dell'oggetto conterrà uno speciale oggetto classe builder che può costruire l'oggetto tramite chiamate di funzione che restituiscono lo stesso oggetto. Ciò consente di ottenere un codice fluido molto più dettagliato e chiaro per un client dell'API. Questo può essere molto più utile nel rappresentare i parametri di una funzione rispetto a un elenco estremamente lungo di argomenti e impedisce il problema comune di un client che accidentalmente combina gli argomenti. Il client è costretto ad essere prolisso nella costruzione dei suoi argomenti.

sendPizza (pizzaBuilder- > buildPeppers () - > buildSausage () - > etc ...)

Uno è in grado di esaminare immediatamente il codice cliente e decifrare l'ampiezza degli argomenti passati a sendPizza.

    
risposta data 03.05.2013 - 03:44
fonte
3

Mi piace che tu separi le opzioni richieste da quelle opzionali. Se non usi un Builder, quindi per i parametri opzionali, anche quando non ci sono parametri richiesti, utilizzerei sicuramente un array associativo o una "mappa". Penso che tu lo chiami solo un "array" perché PHP lo chiama, ma non ne sono sicuro.

Builder Pattern ti consente di creare l'API più a tenuta d'aria, come affermato da @maple_shaft. Impedisce ai client di immettere chiavi non valide nell'array dei parametri e la sua natura funzionale consente di eseguire rapidamente un errore non appena viene passato un valore non valido. Concordo sul fatto che sarebbe la migliore risposta nella maggior parte dei casi.

Ma il pattern Builder può richiedere una buona quantità di lavoro di programmazione iniziale per rendere la tua API facile da usare per i tuoi clienti. Potrebbe non essere come PHP-ish come i tuoi array associativi - non lo saprei. Per completezza sento che dovrei menzionare alcune altre opzioni. Il primo potrebbe essere quello che stai facendo già ...

Mappa dei parametri con nome

class MyApi {
    const Param1Name = 0;
    const Param2Name = 1;
    // etc.

    public function sampleApiMethod($myParamHash) {
        //Method Code
        $localParam1 = $myParamHash[Param1Name]
    }
}

// Load up params using pre-defined symbolic names to prevent typos
$myParamHash = array (MyApi::Param1Name => 5,
                      MyApi::Param2Name => 9);

// call method
sampleApiMethod($myParamHash);

La bellezza di questa opzione (o del costruttore) è che rende chiaro quale parametro è, evitando così molti errori potenziali.

Valori predefiniti

Ho appena fatto una ricerca rapida, e sembra che PHP supporti i valori predefiniti per argomenti . Questi sono probabilmente migliori dei metodi di telescopio, ma ci possono essere alcuni casi in cui i lavori di telescopica e i valori predefiniti non lo sono, quindi menzionerò ...

Metodi di telescopio

Non sono sicuro che funzioni in PHP, ma qualcosa del tipo:

public function sampleApiMethod($reqVal1, $reqVal2, $additionalOptions) {
    //Method Code
}
public function sampleApiMethod($reqVal1, $reqVal2) {
    sampleApiMethod($reqVal1, $reqVal2, null);
}
public function sampleApiMethod($reqVal1) {
    sampleApiMethod($reqVal1, null, null);
}

Sto usando "null" per i valori predefiniti. Ma per un'API, questo rende le cose molto più semplici per il chiamante senza il lavoro di creazione di un costruttore. Basta inserire gli argomenti più comunemente usati per primi e fornire impostazioni predefinite sensibili nei metodi di telescopio.

Riesamina il modello

Quasi tutti i programmi utili modellano alcune cose o azioni del mondo reale. Un'API che accetta 30 parametri mi sembra una bandiera rossa che potrebbe presentare problemi di progettazione di livello superiore nella tua API. Potresti voler fornire un modello per alcune delle cose che stai trasmettendo come valori primitivi. Le persone funzionali modellerebbero le cose in termini di funzioni, le persone OO in termini di oggetti. Fai la tua scelta.

    
risposta data 03.05.2013 - 05:24
fonte

Leggi altre domande sui tag