title: What is the proper way to create an abstraction for apis with large programing surfaces?
body: <p>I'm trying to adapt <a href="https://stackoverflow.com/a/5646876/3691973">this</a> concept to Search. Specifically, I want to begin using Elasitcsearch, but still maintain a proper abstraction layer. However, the Elasticsearch API surface is huge. It exposes not only basic connection creation (which it easily makes sense to abstract away), but also extremely powerful (and therefore potentially complex) extension methods to build indexes and queries. In fact, it's so complex that it already comes with a built in wrapper layer for use in .Net: NEST.</p>
  
  <p>So my question is, is it reasonable to create another abstraction layer on top of that. Something like:</p>
  
  <pre><code>public interface ISearchClient
  {
      IIndexResult Index(IIndexRequest request);
  
      ISearchResult Search(ISearchRequest request);
  
      // Other methods here as appropriate.
  }
  </code></pre>
  
  <p>and then create extension methods to expose most of the power built into NEST? That seems like a ton of wasted effort given that most of the exposed functionality of the IElasticClient used by NEST is already extension methods down into the low level libraries. </p>
  
  <p>Is there a way to expose the existing extension methods handed to me by NEST? Is that wise to do, or does it defeat the whole purpose of implementing my own ISearchClient middleware? Or is the best course of action to create the abstraction layer and then only expose the existing extension methods as necessary? That feels like it's intentionally creating a pile of technical debt that will never be worked through.</p>