2017-03-21 4 views
0

J'ai une méthode qui appelle une API avec HttpClient et construire une liste de clients comme IEnumberable<Customer>. La façon dont cette API fonctionne est qu'elle ne retournera que 100 clients à la fois, et fournira un autre lien dans le contenu JSON pour récupérer les 100 suivants.Comment puis-je utiliser Rx avec C# wait appels pour récupérer des données JSON à partir du Web

Comment puis-je structurer ce code pour extraire les enregistrements de manière itérative sont récupérées et construisent un grand IEnumerable<Customer> et reviennent de cette méthode. Je suis à la recherche de la solution avec Rx.

Task<IEnumerable<Customer>> GetCustomers(string url) 
{ 
    HttpClient client = new HttpClient(); 
    HttpResponseMessage response = await client.GetAsync(url); 
    response.EnsureSuccessStatusCode(); 
    string responseBody = await response.Content.ReadAsStringAsync(); 

    // TODO: Deserialize responseBody and build a new IEnumerable<Customer> 
} 

Json: 

{ 
    nextRecords: '\customers\123' 
    customers: [ 
     { 
      name: 'John Doe' 
     }, 
     { 
      name: 'Mary Doe' 
     } 
     ] 
} 
+1

Pourriez-vous s'il vous plaît fournir le code suffisant pour appeler l'API, indiquez le numéro de page (à savoir que 100 clients à obtenir), puis construire les clients? Aussi, comment savons-nous quand vous avez tous les enregistrements? Il serait alors trivial de créer une méthode Rx pour construire tout le lot. – Enigmativity

+0

(1) L'URI est comme '' '\ customers \' ''. Les clients renvoyés par le serveur sont définis sur 100. Vous ne pouvez pas le modifier depuis le client. (2) La seule façon de savoir qu'il n'y a plus d'enregistrements est en regardant le champ '' 'nextRecords'''. Cette valeur sera vide s'il n'y a plus d'enregistrements. –

+1

Comment le serveur distingue-t-il deux appels clients consécutifs et deux appels clients parallèles? c'est-à-dire deux appels essayant d'obtenir les 100 premiers enregistrements chacun et deux appels essayant d'obtenir les premier et deuxième 100 enregistrements? – Enigmativity

Répondre

2

J'ai changé la signature Task<IEnumerable<Customer>>-IObservable<Customer> pour le rendre plus Rx-like.

Vous devez définir la fonction Func<JObject, IObservable<Customer>> createCustomers.

Essayez d'avoir un aller à ceci:

IObservable<Customer> GetCustomers(string url) 
{ 
    Func<JObject, IObservable<Customer>> createCustomers = jo => { ... }; 
    return Observable.Create<Customer>(o => 
    { 
     var final_url = url + "\\customers"; 
     return 
      Observable 
       .While(
        () => final_url != url, 
        Observable 
         .Using(
          () => new HttpClient(), 
          client => 
           from x in Observable.FromAsync(() => client.GetAsync(final_url)) 
           from y in Observable.Start(() => 
           { 
            x.EnsureSuccessStatusCode(); 
            return x; 
           }) 
           from z in Observable.FromAsync(() => y.Content.ReadAsStringAsync()) 
           from w in Observable.Start(() => 
           { 
            var j = JObject.Parse(z); 
            final_url = url + j.Property("nextRecords").Value; 
            return createCustomers(j); 
           }) 
           from v in w 
           select v)) 
       .Subscribe(o); 
    }); 
}