OData Dart

OData Dart is a library to make fetching data from OData Rest APIs slightly easier. (Slightly 😅)


Compatible with OData v4.0 and v4.01


Not usable for production, this version is experimental


To get data, you will create queries first. There are 2 types of queries, Query<T> and ColletionQuery<T>.

  final instance = OData("api.example.com/v1");

  final ODataResponse simpleExample = await instance
      .single("/api/Person(1)") // Returns Query
      .select("Oid, Name, Age, Phone") // Sets $select fields, fields are seperated by comma. Returns the Query (URL QUERY => $select=Oid,Name,Age,Phone)
      .expand("Facebook") // Sets $expand field, you may use multiple expands, but must set one at a time. (URL QUERY => $expand=Facebook)
      .fetch(); // Fetches [baseUrl]/api/Person(1)?$select=Oid,Name,Age,Phone&$expand=Facebook

  final ODataResponse<LoginDetails> loginExample = await instance
        options: QueryOptions(
          method: "POST",
          requestBody: {
            "Username": "TestUser1234", // I don't like how C# standardizes capitalized variable names :((((
            "Password": "••••••••",
          convertor: (json) => LoginDetails.fromJson(json),
  // You need to set Cookie and the Bearer if needed.

  instance.setCookie(loginExample.response.headers["set-cookie"]); // Now Bearer token and Cookie are appended in the request HEADER by default. Set QueryOptions.tryUseAuth to false to omit it from the header

  final ODataResponse<Person> convertorExample = await instance
        options: QueryOptions(
        convertor: (json) => Person.fromJson(json),
      .select("Oid, Name, Age, Phone")

  final ODataCollectionResponse<Person> complexExample = await instance
        tryUseAuth: false,
        options: CollectionQueryOptions(
          tryUseAuth: false, // When true, adds Cookie and Bearer token in the header if available. True by default.
          convertor: (json) => Person.fromJson(json), // Convertor function; must pass convertor for single instance.
      ) // Returns CollectionQuery<T>
      // .selectList(["Oid", "Username", "Name", "Age"]) // Alternative option
        .expand() // This creates ExpandQueryField(), which is special class to handle nested $expand, $select, etc.
        .select("Oid") // This selects single field, "Oid", from /api/Person/ModifiedBy
        .expand("Facebook".expand()) //
      .count() // This ensures @odata.count is included in collection queries