Witam.
Ostatnio mi się na YouTube pokazała propozycja video z konferencji na temat GraphQL i tak sobie pomyślałem, dlaczego tego się nie używa w API w ASP .NET Core? Słyszałem już o GraphQL wcześniej, ale jakoś nie miałem weny twórczej na drążenie co to i po co mi to, a teraz, jak już wiem do czego jest zdolny, dziwię się dlaczego tego nie ma w API. Rozumiem, że te zapytania są czasem bardzo skomplikowane, ale przecież do API łączą się "profesjonaliści', a nie szara pani basia z działu sprzedaży.
Czy tylko mnie się wydaje, że to połączenie mogłoby być potężne?
GraphQL rozwiązuje problem under/over fetchingu, jeśli masz taki problem to GraphQL jest rozwiązaniem. Jeśli nie masz takiego problemu to używanie GraphQL jest czystym overengineeringiem i żaden hype ze strony reactowego community tego nie zmieni :D.
Serio? To tyle? Owszem wszędzie są plusy i minusy, ale dlaczego akurat GraphQL nadaje się do rozwiązania tylko problemu under/over fetchingu?
Czym się różni GraphQL od dynamic linq na expressionach?
Korzystając trochę z kodu @Juhas na expr from str. oraz ukradniętego z SO kodu na zamiane string to func
Wyszło mi, że możemy sobie dynamicznie definiować Select
oraz Where
Jedyne problemy jakie tutaj zauważyłem to:
-
Jeżeli pomijamy jakąś kolumnę, to chyba wstawi się tam wartość
default
, więc trzeba byłoby?
porobić albo po prostu poprawnie obsłużyć po stronie frontu, który w sumie sam sobie wybiera co chcę dostać, więc raczej nie ma problemu. -
Wygenerowanie
Expression
z stringa to nie jest tania operacja
Output:
var dynamicSelect = "Id,Name";
1
null
Name321
2
null
Name123
2
234
Name123
var dynamicSelect = "Id,Age";
1
155
2
234
2
234
Name123
public class Test
{
public int Id { get; set; }
public int? Age { get; set; }
public string Name { get; set; }
}
public static void Main()
{
var opt = new DbContextOptionsBuilder<Context>().UseInMemoryDatabase(Guid.NewGuid().ToString()).Options;
var context = new Context(opt);
context.Add(new Test { Id = 0, Age = 155, Name = "Name321" });
context.Add(new Test { Id = 2, Age = 234, Name = "Name123"});
context.SaveChanges();
var dynamicSelect = "Id,Name";
var result = context.Tests.Select(CreateNewStatement<Test>(dynamicSelect)).ToList(); // count = 2
var expr = ExpressionFromStr<Test>("x => x.Age % 2 == 0").Result;
var result2 = context.Tests.Where(expr).ToList(); // count = 1
foreach (var test in result.Union(result2))
{
Console.WriteLine(test.Id);
Console.WriteLine(test.Age?.ToString() ?? "null"); // aby ładniej wyświetlić
Console.WriteLine(test.Name);
Console.WriteLine();
}
}
public async static Task<Expression<Func<T, bool>>> ExpressionFromStr<T>(string expressionStr)
{
var options = ScriptOptions.Default.AddReferences(typeof(T).Assembly);
return await CSharpScript.EvaluateAsync<Expression<Func<T, bool>>>(expressionStr, options);
}
public static Func<T, T> CreateNewStatement<T>(string fields)
{
var xParameter = Expression.Parameter(typeof(T), "o");
var xNew = Expression.New(typeof(T));
var bindings = fields.Split(',').Select(o => o.Trim()).Select(o =>
{
var mi = typeof(T).GetProperty(o);
var xOriginal = Expression.Property(xParameter, mi);
return Expression.Bind(mi, xOriginal);
}
);
var xInit = Expression.MemberInit(xNew, bindings);
var lambda = Expression.Lambda<Func<T, T>>(xInit, xParameter);
return lambda.Compile();
}
Może się mylę ale przyglądając się graphql wygląda to jak by dac dostęp do całej bazy danych każdemu kto korzysta z aplikacji. Każdy z wiedzą będzie w stanie generować swoje zapytania z konsoli przeglądarki.
No tak, z tym wyjątkiem, że nie trzeba pisać tego co wcześniej napisał @WeiXiao. Oczywiście nie udostępniasz API bez autoryzacji, więc nie mając tokena, nie masz tej władzy.
liwaskiewicz napisał(a):
Może się mylę ale przyglądając się graphql wygląda to jak by dac dostęp do całej bazy danych każdemu kto korzysta z aplikacji. Każdy z wiedzą będzie w stanie generować swoje zapytania z konsoli przeglądarki.
Zapytania do API a nie do bazy, Więc pod względem bezpieczeństwa nic się nie zmienia. Jeśli API nie wystawia konkretnych danych to GraphQL nie zdziała tu cudów i dostępu do tych danych mieć nie będzie.