Registratore opzionale per un'implementazione dell'API

1

Dire che voglio creare un'implementazione C # di un'API per alcuni servizi di terze parti e voglio avere un'opzione per ottenere i post e le risposte JSON in qualche modo, quale sarebbe un modo elegante per farlo?

Esempio di un metodo:

public class MyApiImplementation{
    public PaymentRespose CreatePayment(decimal amount, string orderId){
        //some code here
    }
}

Quando chiamo quel metodo (compilato), voglio ottenere da JSON la sottostante risposta di riposo, così posso eseguirne il debug o registrarlo.

Non voglio fare qualcosa di simile ...:

public class MyApiImplementation{
    public PaymentRespose CreatePayment(decimal amount, string orderId, out string json){
        //some code here
    }
}

Quando chiamo l'api, voglio essere in grado di ottenere il json in qualche modo.

public api = new MyApiImplementation();
PaymentResponse pr = api.CreatePayment(100M, "ORDER1234");
string json = ???

Potrei includere il json in PaymentResponse, ma ... Sembra che non appartenga a questo.

Sto pensando a un logger opzionale di qualche tipo in un overload di contructor.

Qualche buon suggerimento su come implementarlo? Come potrebbe essere?

Modifica:

Followup

Non penso di essere stato abbastanza chiaro nella mia descrizione, quindi permettimi di provare a elaborare e fornire un po 'più di codice.

Scopo

Sto creando una classe di libreria, che è un wrapper C # attorno all'interfaccia REST per un fornitore di pagamenti. Fornirò questa libreria agli sviluppatori tramite Nuget.

Questo è quello che faccio oggi

public class AwesomePaymentClient{
    public Payment CreatePayment(string orderId, string currency, out string json)
    {
        var request = CreatePostRequest("payments");

        request.AddParameter("currency", currency);
        request.AddParameter("order_id", orderId);

        var response = Client.Execute<Payment>(request);
        json = response.Content;
        VerifyResponse(response);

        return response.Data;
    }
    //all other methods omitted from example
}

Non mi piace particolarmente

out string json
bit, ma mi piacerebbe che gli sviluppatori avessero un modo per ottenere l'effettiva risposta JSON per i propri scopi di debug / logging.

Potrei creare un sovraccarico che non ha il parametro out, ma ritengo che rende l'API un po 'sporco - e che sia una preoccupazione separata.

Potrei anche includere una proprietà json su Payment, ma ancora una volta mi piacerebbe tenerla separata.

Quindi sto pensando, forse faccio un sovraccarico per un costruttore, che contiene una specie di registratore o ... Qualcosa, che non riesco a capire cosa sia.

Il middleware ecc. è fuori discussione, dato che sto solo fornendo una libreria.

Spero che questo aiuti a chiarire le mie intenzioni. :)

    
posta Kjensen 08.11.2017 - 18:44
fonte

2 risposte

1

Con accesso concorrente a un'istanza, la risposta JSON non può essere archiviata in una proprietà (perché una richiesta diversa potrebbe sovrascrivere il suo valore prima che venga letta).

Con un "logger", è ancora necessario in qualche modo scoprire quale risposta JSON appartiene a quale richiesta, quindi avrai bisogno di un identificatore.

Preferirei offrire due versioni dell'interfaccia: una "normale" e una "estesa", come:

public interface IPaymentClient
{
    IPayment CreatePayment(string orderId, string currency);
}
public interface IPaymentClientEx: IPaymentClient
{
    IPayment CreatePayment(string orderId, string currency, out string json);
}

Con implementazioni come

public class AwesomePaymentClient: IPaymentClient 
{
    public IPayment CreatePayment(string orderId, string currency)
    {
        var request = CreatePaymentRequest(orderId, currency);
        var response = ExecutePaymentRequest(request);
        return response.Data;
    }
    protected IRequest CreatePaymentRequest(string orderId, string currency)
    {
        var request = CreatePostRequest("payments");
        request.AddParameter("currency", currency);
        request.AddParameter("order_id", orderId);
        return request;
    }
    protected IResponse ExecutePaymentRequest(IRequest request)
    {
        var response = Client.Execute<Payment>(request);
        VerifyResponse(response);
        return response;
     }
}
public class AwesomePaymentClientEx: AwesomePaymentClient, IPaymentClientEx
{
    public IPayment CreatePayment(string orderId, string currency, out string json)
    {
        var request = CreatePaymentRequest(orderId, currency);
        var response = ExecutePaymentRequest(request);
        json = response.Content;
        return response.Data;
    }
}

Ora lo sviluppatore può scegliere la versione di cui ha bisogno. Non è perfettamente pulito, ma suppongo che si avvicini alle tue esigenze. E la versione "estesa" offre anche le funzioni "normali".

    
risposta data 09.11.2017 - 12:15
fonte
2

L'API dovrebbe includere un'interfaccia logger per ogni metodo esposto. Forse qualcosa del genere:

public IPayment CreatePayment(string orderId, string currency, ILogger logger)

Quindi ogni utente dell'API potrebbe implementare il programma di registrazione come meglio crede che passi in un'implementazione di un logger.

Nella chiamata al metodo, aggiungi semplicemente (o simile):

Logger.LogResponse(string response);

Quindi l'implementazione della registrazione eseguirà la registrazione su file, db, ecc. Deciderà l'utente della tua API. Gestisci internamente la conversione / serializzazione del JSON come meglio credi.

Fornisci l'interfaccia, i tuoi utenti API implementano. Se non è stato eseguito alcun passaggio (nullo), è possibile che un'implementazione interna utilizzi System.Diagnostics o simile.

    
risposta data 09.11.2017 - 16:55
fonte

Leggi altre domande sui tag