###Update:
So it was written, so it is done.
var questionWithStuff =
ctx // soapi context
.Official // convenience properties for known sites
.StackOverflow
.Questions
.Tagged("asp.net","c#")
.FromDate("january 1, 2001")
.ToDate(new DateTime(2020, 10, 10))
.WithBody
.WithAnswers
.WithComments
.Page(1)
.PageSize(2)
.Pages(3)
.Sort(QuestionSort.Votes)
.Min(1)
.Max(100)
.Order(SortOrder.Asc)
.ToList();
Assert.AreEqual(6, questionWithStuff.Count);
// issues the following requests
// http://api.stackoverflow.com/1.0/questions?answers=true&body=true&comments=true&fromdate=978307200&max=100&min=1&order=Asc&page=1&pagesize=2&sort=Votes&tagged=asp.net%3bc%23&todate=1602288000
// http://api.stackoverflow.com/1.0/questions?answers=true&body=true&comments=true&fromdate=978307200&max=100&min=1&order=Asc&page=2&pagesize=2&sort=Votes&tagged=asp.net%3bc%23&todate=1602288000
// http://api.stackoverflow.com/1.0/questions?answers=true&body=true&comments=true&fromdate=978307200&max=100&min=1&order=Asc&page=3&pagesize=2&sort=Votes&tagged=asp.net%3bc%23&todate=1602288000
The question is, would anyone be interested in using code that looks like this? Just like this and does what it says it will do?
Before I go any farther in extending Soapi.CS and Soapi.JS, I need to know if there is interest. Otherwise I will spend my time writing some apps.
I am actively begging for constructive or informative feedback, positive or negative. Please. Sometimes it feels like I am writing in the wilderness. ;-(
// what you see is what you would get. Imagine similar in JavaScript
// while it looks like LINQ, it is not quite. I am simply planning to
// use dynamic proxies (ala NHibernate) to lazy load from the API.
ApiContext.Initialize(key);
// initialize simply fetches all sites and prepares them with
// the necessary data and functionality to serve as the root for
// all queries for that site.
// initialization is done on a static method and happens only once
// for each appDomain. (appdomain is a scope of execution,
// an application for example, NOT a web domain)
ApiContext ctx = new ApiContext();
// an ApiContext instance maintains an objectGraph cache
// ensuring that when a new object is brought in from an http
// query, if it is already in the graph, update it in place,
// otherwise add it to the graph at the appropriate location
User codePoet = ctx.Sites("api.stackapps.com").User(14);
foreach(Question q in codePoet.Questions())
{
Console.WriteLine(q.Title);
foreach(Answer a in q.Answers())
{
Console.WriteLine(a.Owner.DisplayName + " " + a.Owner.Reputation));
}
}
// so you noticed the lazy loading in the expressions above - this is where it
// gets more interesting....
IEnumerable<Question> codePoetsQuestionsOnStackOverflow
= codePoet.UserAssociation.Users
.First(u=>u.Site.SiteId=="api.stackoverflow.com").Questions();
// what you see is a navigation from my stackapps User up into
// it's UserAssociation object (stackauth /users/{id}/associated),
// finds the user who's site is stackoverflow and then returns all
// of my stackoverflow questions.
// Again, there are no strings - this code will run and give you exactly
// what it says it will.
Status
The lazy loading proof of concept is working just as you see above and will be ready for release in a few days.
The idea of layering a LINQ provider on top of this is on hold. See Luke's answer.
// real live linq
var someInterstingQuestions = ctx.Sites("api.stackoverflow.com")
.Users.Where(u=>u.Reputation > 20000)
.Questions.Where(q=>(q.Title.Contains("foo") ||
q.Title.Contains("bar")) && q.UpVotes > 10).Skip(5).Take(10);
// the Skip is a multiple of the take, so get the 6th page of 10
//
Can we get some pre-orders please?