What is GraphqlToTsql?
It is a .NET component that translates GraphQL queries into native T-SQL.
It turns this…
query hammerQuery ($name: String) {
hammer: product (name: $name) {
name
price
orderDetails {
orderId
quantity
order {
date
seller {
city
state
distributor {
name
}
}
}
}
}
}
Into this…
-------------------------------
-- Operation: hammerQuery
-------------------------------
SELECT
-- hammer (t1)
JSON_QUERY ((
SELECT
t1.[Name] AS [name]
, t1.[Price] AS [price]
-- hammer.orderDetails (t2)
, JSON_QUERY ((
SELECT
t2.[OrderId] AS [orderId]
, t2.[Quantity] AS [quantity]
-- hammer.orderDetails.order (t3)
, JSON_QUERY ((
SELECT
t3.[Date] AS [date]
-- hammer.orderDetails.order.seller (t4)
, JSON_QUERY ((
SELECT
t4.[City] AS [city]
, t4.[State] AS [state]
-- hammer.orderDetails.order.seller.distributor (t5)
, JSON_QUERY ((
SELECT
t5.[Name] AS [name]
FROM [Seller] t5
WHERE t4.[DistributorName] = t5.[Name]
FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER)) AS [distributor]
FROM [Seller] t4
WHERE t3.[SellerName] = t4.[Name]
FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER)) AS [seller]
FROM [Order] t3
WHERE t2.[OrderId] = t3.[Id]
FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER)) AS [order]
FROM [OrderDetail] t2
WHERE t1.[Name] = t2.[ProductName]
FOR JSON PATH, INCLUDE_NULL_VALUES)) AS [orderDetails]
FROM [Product] t1
WHERE t1.[Name] = @name
FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER)) AS [hammer]
FOR JSON PATH, INCLUDE_NULL_VALUES, WITHOUT_ARRAY_WRAPPER;
Hmm, is it easy?
We all know GraphQL can be hard. GraphqlToTsql makes it a little easier.
- NO servers to install
- NO resolvers to write
- NO new technologies to add to your stack
GraphqlToTsql is a NuGet package, not a system or a service.
- You supply the API endpoint to receive GraphQL queries
- You supply a connection string to your SQL Server or Azure SQL database
- You write entity mappings
- GraphqlToTsql will to translate the GraphQL into a comprehensive T-SQL query and send it to your database. You get back the data as a JSON string.
Sounds easy, what’s the catch?
Actually there are three catches…
- GraphqlToTsql only works with specific technologies
- .NET (GraphqlToSql targets .NET Standard 2.0)
- SQL Server / Azure SQL. The T-SQL that is generated is specific to Microsoft databases.
-
At this time, only the query portion of the GraphQL spec is supported. Mutations are not supported.
- You have to write entity mappings. They’re easier to write than resolvers, and they’re powerful. They control what parts of your database are available to GraphQL queries, and how things are named. Your Entity Mappers can include custom join criteria, virtual tables, and computed values.
To give you the idea, here’s a sample entity mapping.
public class OrderEntity : EntityBase
{
public static OrderEntity Instance = new OrderEntity();
public override string Name => "order";
public override string DbTableName => "Order";
public override string[] PrimaryKeyFieldNames => new[] { "id" };
public override long? MaxPageSize => 1000L;
protected override List<Field> BuildFieldList()
{
return new List<Field>
{
Field.Column(this, "id", "Id", ValueType.Int, IsNullable.No),
Field.Column(this, "sellerName", "SellerName", ValueType.String, IsNullable.No, Visibility.Hidden),
Field.Column(this, "date", "Date", ValueType.String, IsNullable.No),
Field.Column(this, "shipping", "Shipping", ValueType.Float, IsNullable.No),
Field.Row(SellerEntity.Instance, "seller", new Join(
()=>this.GetField("sellerName"),
()=>SellerEntity.Instance.GetField("name"))
),
Field.Set(OrderDetailEntity.Instance, "orderDetails", IsNullable.No, new Join(
()=>this.GetField("id"),
()=>OrderDetailEntity.Instance.GetField("orderId"))
)
};
}
}
The Documentation page takes you through all the details.
License
GraphqlToTsql is licensed under the MIT License.