.NET中SQL數據庫的GraphQL API

您可能已經閱讀了大量關於GraphQL的文章,並且已經瞭解了這種API技術的所有優缺點,作爲REST API的替代方案。但是,讓我們不久回顧一下GraphQL是什麼,它的主要目的,以及我們如何在現實生活中使用它。

關於GraphQL的簡短信息

GraphQL於2015年由Facebook發佈,定位爲着名的RESTful架構風格的替代品。您只有一個Web API端點,而不是數百個Web API方法(顯然可能有不同的版本),您可以獲得有關字段的所有信息(字段類型,是否需要等)。從本質上講,GraphQL接受查詢 - 這是一種JSON格式的數據 - 並嘗試將其解析爲先前定義的模式。

您可以發佈兩種類型的查詢:

  • 查詢 - 獲取多個數據,僅查詢查詢中定義的那些字段

  • 變異 - 用於創建,更新或刪除數據

在項目中使用GraphQL之前,我們應該定義包含所有可能的實體和實體字段的模式,並解決我們定義獲取或更新數據的方式和位置。圖片標題

獲取數據方法概述

實際上,來自客戶端頁面的大量請求只是從數據庫(或其他數據源,如Elasticsearch)獲取數據,因此讓我們簡要地檢查一下我們可以用來獲取數據的方法,並澄清每種方法可能存在的缺陷。

第一個 - 我說最着名的 - 是使用實體框架(EF)。在我看來,EF有點複雜,特別是如果我們只是談論從數據庫獲取數據。此外,如果數據庫表先前已更新,我們不應忘記更新項目中定義的模型。

第二種方法基於輕量級ORM NReco.Data,它具有廣泛的DB適配器(允許連接到任何流行的數據庫 - MSSQL,PostgreSQL,MySQL,Elasticsearch等)。但是,在我們的表更改時,我們仍然遇到更新方案的問題。讓我們看一個允許我們在JSON格式的文件中定義所有模式(甚至關係)的組件 - GraphQL.Net API到SQL-db

讓我們配置架構並逐步運行.NET Core Web Application的幾個查詢:

1.首先,讓我們在Startup.cs中設置數據庫配置字符串和模式定義

public  void  ConfigureServices(IServiceCollection  services){
  服務。AddMvc()。SetCompatibilityVersion(compatibilityVersion進行。Version_2_1);
  服務。AddSingleton < IDbFactory,DbFactory >((servicePrv)=> {
    // db-provider特定的配置代碼:
    返回 新 DbFactory(微軟。數據。sqlite的。SqliteFactory。實例){
      LastInsertIdSelectText  =  “SELECT last_insert_rowid()”
    };
  });
  服務。AddSingleton < IDbCommandBuilder,DbCommandBuilder >((servicePrv)=> {
    VAR  dbCmdBuilder  =  新 DbCommandBuilder將(servicePrv。GetRequiredService < IDbFactory >());
    dbCmdBuilder。SelectTemplate  =  “SELECT @columns FROM @ table @ where [WHERE {0}] @ orderby [ORDER BY {0}] @recordcount [LIMIT {0}] @recordoffset [OFFSET {0}]” ;
    //在這裏初始化數據視圖:
    return  dbCmdBuilder ;
  });

  服務。AddScoped < IDbConnection >((servicePrv)=> {
    var  dbFactory  =  servicePrv。GetRequiredService < IDbFactory >();
    var  conn  =  dbFactory。CreateConnection();
    康涅狄格州。ConnectionString  =  String。格式(“Filename = {0}”,路徑。組合(ApplicationPath,“../ Data / northwind.db”));
    返回 康涅狄格州 ;
  });

  服務。AddScoped < DbDataAdapter >();
  //通過json-file配置模式
  服務。AddScoped < IGraphqlAdapter >((servicePrv)=> {
    var  dbAdapter  =  servicePrv。GetRequiredService < DbDataAdapter >();
    var  graphqlAdapter  =  new  GraphqlDbAdapter(
      dbAdapter,
      JsonConvert。DeserializeObject < GraphqlConfiguration >(
        系統。IO。檔案。ReadAllText(Path。組合(ApplicationPath,“schemaDbDefinition.json”))
      )
    );

    return  graphqlAdapter ;
  });
}

2.第二步是定義“schemaDbDefinition.json”文件,其中我們有下一個屬性:

  • 選項 - 它是一個非必要的屬性,可能會被省略; 包含過濾器,分頁,排序等

    • 默認情況下啓用分頁,用於在查詢中定義排序參數(sortBy,direction)

    • 默認情況下,排序已啓用,用於在查詢中定義排序參數(sortBy,direction)

    • 默認情況下,過濾器已啓用,用於在查詢中定義過濾器參數(默認情況下爲“過濾器”)

  • SchemaObjects - 基於來自DB的數據表的已定義GraphQL對象的數組

    • Relex - 字符串表達式(閱讀更多信息NReco.Relex),其中所有字段值都來自父模式對象,可以在條件中使用。

    • SingleName - GraphQL查詢中單個對象的名稱

    • ListName - GraphQL查詢中對象列表的名稱

    • 表 - 數據庫表名

    • 描述 - 可選字段; 出現在GraphiQL IDE中幷包含簡短描述

    • 字段 - GraphQL查詢中可用的所有字段

    • RelatedObjects - 相關對象的數組; 只能由架構中定義的對象使用

最終,它應該是這樣的:

{
  “選項”:{
  “分頁”:{
  “ArgumentNameForFirst”:“limitItems”
  }
  },
  “SchemaObjects”:[
    {
      “SingleName”:“客戶”,
      “ListName”:“客戶”,
      “表”:“客戶”,
      “描述”:“客戶表 - 包含有關客戶的數據”,
      “領域”:[
      {
        “姓名”:“id”,
        “專欄”:“客戶ID”,
        “DataType”:“string”,
        “描述”:“唯一標識符 - 也用於連接訂單”
      },
      {
        “名稱”:“公司名稱”,
        “DataType”:“string”
      },
      {
        “名稱”:“ContactName”,
        “DataType”:“string”
      }
      ]
      “RelatedObjects”:[
        {
        “名稱”:“順序”,//指相關對象的名稱
        “Relex”:“訂單(CustomerID = \”id \“:var)[*]”  //用於加載相關對象的查詢
        },
        {
        “名稱”:“訂單”,
        “Relex”:“訂單(CustomerID = \”id \“:var)[*]”
        }
      ]
    },
    {
      “SingleName”:“訂單”,
      “ListName”:“訂單”,
      “表”:“訂單”,
      “領域”:[
        {
          “名稱”:“orderId”,
          “列”:“OrderID”,
          “DataType”:“int32”
        },
        {
          “名稱”:“customerId”,
          “專欄”:“客戶ID”,
          “DataType”:“string”
        },
        {
          “名稱”:“OrderDate”,
          “DataType”:“datetime”
        },
        {
          “名稱”:“運費”,
          “DataType”:“十進制”
        }
      ]
    }
  ]
}

3.讓我們將一個GraphQL適配器添加到API方法的控制器:

公共 類 GraphQLRequest {
  public  string  OperationName { get ; 設置 ; }
  public  string  Query { get ; 設置 ; }
  public  JObject  Variables { get ; 設置 ; }
}

[ HttpPost ]
public  async  Task < IActionResult >  PostAsync([ FromBody ] GraphQLRequest  queryRequest,CancellationToken  cancellationToken){
  var  graphqlResult  =  await  _graphqlAdapter。ExecuteToJsonAsync(
  新的 GraphQLQuery {
    Query  =  queryRequest。查詢,
    OperationName  =  queryRequest。OperationName,
    變量 =  queryRequest。變量。ToInputs()
  },
  的CancellationToken
);

返回 Ok(
graphqlResult
);
}

4.讓我們的訂單獲得所有客戶:

圖片標題

5.或者使用最後2個訂單獲取特定客戶的數據:

圖片標題

6.應用過濾器並獲得超過870運費的所有訂單:

圖片標題

摘要

使用NReco.GraphQL定義模式,數據獲取非常簡單,只需幾步即可完成。您不再需要創建類來定義GraphQL方案並在更新後重建整個解決方案 - 您只需稍微更改JSON文件即可。NReco.GraphQL的另一個好處是這個數據庫適配器可以輕鬆連接到任何流行的數據庫。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章