Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Introduction
- Queries
- Data Types
- Lists and Non-Null
- Arguments
- Aliases
- Fragments
- Variables
- Directives
- Mutations
- //========================= Introduction =========================
- // Here is a "Hello World" example for GraphQL .NET.
- using System;
- using GraphQL;
- using GraphQL.Types;
- public class Program
- {
- public static void Main(string[] args)
- {
- var schema = Schema.For(@"
- type Query {
- hello: String
- }
- ");
- var json = schema.Execute(_ =>
- {
- _.Query = "{ hello }";
- _.Root = new { Hello = "Hello World!" };
- });
- Console.WriteLine(json);
- }
- }
- // Output
- {
- "data": {
- "hello": "Hello World!"
- }
- }
- // Пример
- type Droid {
- id: String!
- name: String!
- }
- type Query {
- hero: Droid
- }
- // Schema First Approach
- public class Droid
- {
- public string Id { get; set; }
- public string Name { get; set; }
- }
- public class Query
- {
- [GraphQLMetadata("hero")]
- public Droid GetHero()
- {
- return new Droid { Id = "1", Name = "R2-D2" };
- }
- }
- var schema = Schema.For(@"
- type Droid {
- id: String!
- name: String!
- }
- type Query {
- hero: Droid
- }
- ", _ => {
- _.Types.Include<Query>();
- });
- var json = schema.Execute(_ =>
- {
- _.Query = "{ hero { id name } }";
- });
- // Output
- {
- "data": {
- "hero": {
- "id": "1",
- "name": "R2-D2"
- }
- }
- }
- // GraphType First Approach
- using System;
- using GraphQL;
- using GraphQL.Types;
- public class Droid
- {
- public string Id { get; set; }
- public string Name { get; set; }
- }
- public class DroidType : ObjectGraphType<Droid>
- {
- public DroidType()
- {
- Field(x => x.Id).Description("The Id of the Droid.");
- Field(x => x.Name).Description("The name of the Droid.");
- }
- }
- public class StarWarsQuery : ObjectGraphType
- {
- public StarWarsQuery()
- {
- Field<DroidType>(
- "hero",
- resolve: context => new Droid { Id = "1", Name = "R2-D2" }
- );
- }
- }
- public class Program
- {
- public static void Main(string[] args)
- {
- var schema = new Schema { Query = new StarWarsQuery() };
- var json = schema.Execute(_ =>
- {
- _.Query = "{ hero { id name } }";
- });
- Console.WriteLine(json);
- }
- }
- // Output
- {
- "data": {
- "hero": {
- "id": "1",
- "name": "R2-D2"
- }
- }
- }
- // Schema First Nested Types
- public class Droid
- {
- public string Id { get; set; }
- public string Name { get; set; }
- }
- public class Character
- {
- public string Name { get; set; }
- }
- public class Query
- {
- [GraphQLMetadata("hero")]
- public Droid GetHero()
- {
- return new Droid { Id = "1", Name = "R2-D2" };
- }
- }
- [GraphQLMetadata("Droid", IsTypeOf=typeof(Droid))]
- public class DroidType
- {
- public string Id(Droid droid) => droid.Id;
- public string Name(Droid droid) => droid.Name;
- // these two parameters are optional
- // ResolveFieldContext provides contextual information about the field
- public Character Friend(ResolveFieldContext context, Droid source)
- {
- return new Character { Name = "C3-PO" };
- }
- }
- var schema = Schema.For(@"
- type Droid {
- id: String!
- name: String!
- friend: Character
- }
- type Character {
- name: String!
- }
- type Query {
- hero: Droid
- }
- ", _ => {
- _.Types.Include<DroidType>();
- _.Types.Include<Query>();
- });
- var json = schema.Execute(_ =>
- {
- _.Query = "{ hero { id name friend { name } } }";
- });
- // Output
- {
- "data": {
- "hero": {
- "id": "1",
- "name": "R2-D2",
- "friend": {
- "name": "C3-PO"
- }
- }
- }
- }
- //=========================== Queries ============================
- // To perform a query you need to have a root Query object that is an ObjectGraphType
- // Queries should only fetch data and never modify it. You can only have a single root Query object
- // Queries are executed in parallel
- query {
- hero {
- id
- name
- }
- }
- // If you have only a single query, you can use shorthand syntax
- hero {
- id
- name
- }
- // To provide an Operation name for your query, you add it after the query keyword
- // An Operation name is optional if there is only a single operation in the request
- query MyHeroQuery {
- hero {
- id
- name
- }
- }
- // You can also provide that operation name to the ExecutionOptions
- var schema = new Schema { Query = new StarWarsQuery() };
- var json = schema.Execute(_ =>
- {
- _.OperationName = "MyHeroQuery";
- _.Query = @"
- query MyHeroQuery {
- hero {
- id
- name
- }
- }
- ";
- });
- public class StarWarsQuery : ObjectGraphType
- {
- public StarWarsQuery()
- {
- Field<DroidType>(
- "hero",
- resolve: context => new Droid { Id = "1", Name = "R2-D2" }
- );
- }
- }
- //========================== Data Types ==========================
- // Простые - String, Int, Float, Boolean, ID
- // OBJECTS
- // GraphQL
- type Droid {
- name: String
- appearsIn: [Episode]
- }
- // GraphQL .NET
- public class DroidType : ObjectGraphType<Droid>
- {
- public DroidType()
- {
- Name = "Droid";
- Description = "A mechanical creature in the Star Wars universe.";
- Field(d => d.Name, nullable: true).Description("The name of the droid.");
- Field<ListGraphType<EpisodeEnum>>("appearsIn", "Which movie they appear in.");
- }
- }
- // .NET
- public class Droid
- {
- public string Name { get; set; }
- public List<Episode> AppearsIn { get; set; }
- }
- // ENUMERATIONS
- // GraphQL
- enum Episode {
- NEWHOPE
- EMPIRE
- JEDI
- }
- // GraphQL .NET
- // You can manually create the EnumerationGraphType
- public class EpisodeEnum : EnumerationGraphType
- {
- public EpisodeEnum()
- {
- Name = "Episode";
- Description = "One of the films in the Star Wars Trilogy.";
- AddValue("NEWHOPE", "Released in 1977.", 4);
- AddValue("EMPIRE", "Released in 1980.", 5);
- AddValue("JEDI", "Released in 1983.", 6);
- }
- }
- // Or you can use the generic version passing it a .NET enum which will populate the values for you (excluding description)
- // The Name will default to the .NET Type name, which you can override in the constructor
- public class EpisodeEnum : EnumerationGraphType<Episodes>
- {
- }
- // .NET
- public enum Episodes
- {
- NEWHOPE = 4,
- EMPIRE = 5,
- JEDI = 6
- }
- //====================== Lists and Non-Null ======================
- // Object types, scalars, and enums are the only kinds of types you can define in GraphQL
- // But when you use the types in other parts of the schema, or in your query variable declarations, you can apply
- // additional type modifiers that affect validation of those values. Let's look at an example:
- type Character {
- name: String!
- appearsIn: [Episode]!
- }
- // Here, we're using a String type and marking it as Non-Null by adding an exclamation mark, ! after the type name
- // This means that our server always expects to return a non-null value for this field, and if it ends up getting a null
- // value that will actually trigger a GraphQL execution error, letting the client know that something has gone wrong
- // The Non-Null type modifier can also be used when defining arguments for a field, which will cause the GraphQL server
- // to return a validation error if a null value is passed as that argument, whether in the GraphQL string or in the variables
- query DroidById($id: ID!) {
- droid(id: $id) {
- name
- }
- }
- // Lists work in a similar way: We can use a type modifier to mark a type as a List, which indicates that this field will
- // return an array of that type. In the schema language, this is denoted by wrapping the type in square brackets, [ and ]
- // It works the same for arguments, where the validation step will expect an array for that value
- // The Non-Null and List modifiers can be combined. For example, you can have a List of Non-Null Strings:
- myField: [String!]
- // This means that the list itself can be null, but it can't have any null members. For example, in JSON:
- myField: null // valid
- myField: [] // valid
- myField: ['a', 'b'] // valid
- myField: ['a', null, 'b'] // error
- Now, let's say we defined a Non-Null List of Strings:
- myField: [String]!
- // This means that the list itself cannot be null, but it can contain null values:
- myField: null // error
- myField: [] // valid
- myField: ['a', 'b'] // valid
- myField: ['a', null, 'b'] // valid
- // You can arbitrarily nest any number of Non-Null and List modifiers, according to your needs
- //=========================== Arguments ==========================
- // You can provide arguments to a field. You can use GetArgument on ResolveFieldContext to retrieve argument values
- // GetArgument will attempt to coerce the argument values to the generic type it is given, including primitive values,
- // objects, and enumerations. You can gain access to the value directly through the Arguments dictionary on ResolveFieldContext
- query {
- droid(id: "123") {
- id
- name
- }
- }
- // Schema First
- public class Droid
- {
- public string Id { get; set; }
- public string Name { get; set; }
- }
- public class Query
- {
- private List<Droid> _droids = new List<Droid>
- {
- new Droid { Id = "123", Name = "R2-D2" }
- };
- [GraphQLMetadata("droid")]
- public Droid GetDroid(string id)
- {
- return _droids.FirstOrDefault(x => x.Id == id);
- }
- }
- var schema = Schema.For(@"
- type Droid {
- id: ID!
- name: String
- }
- type Query {
- droid(id: ID!): Droid
- }
- ", _ => {
- _.Types.Include<Query>();
- });
- var json = schema.Execute(_ =>
- {
- _.Query = $"{{ droid(id: \"123\") {{ id name }} }}";
- });
- // GraphType First
- public class Droid
- {
- public string Id { get; set; }
- public string Name { get; set; }
- }
- public class DroidType : ObjectGraphType
- {
- public DroidType()
- {
- Field<NonNullGraphType<IdGraphType>>("id");
- Field<StringGraphType>("name");
- }
- }
- public class StarWarsQuery : ObjectGraphType
- {
- private List<Droid> _droids = new List<Droid>
- {
- new Droid { Id = "123", Name = "R2-D2" }
- };
- public StarWarsQuery()
- {
- Field<DroidType>(
- "droid",
- arguments: new QueryArguments(
- new QueryArgument<IdGraphType> { Name = "id" }
- ),
- resolve: context =>
- {
- var id = context.GetArgument<string>("id");
- return _droids.FirstOrDefault(x => x.Id == id);
- }
- );
- }
- }
- var schema = new Schema { Query = new StarWarsQuery() };
- var json = schema.Execute(_ =>
- {
- _.Query = $"{{ droid(id: \"123\") {{ id name }} }}";
- })
- //============================ Aliases ===========================
- {
- empireHero: hero(id: "1") {
- name
- }
- jediHero: hero(id: "2") {
- name
- }
- }
- //=========================== Fragments ==========================
- // Fragments let you construct sets of fields and then include them in queries where you need to.
- query {
- leftComparison: hero(id: "1") {
- ...comparisonFields
- }
- rightComparison: hero(id: "2") {
- ...comparisonFields
- }
- }
- fragment comparisonFields on Character {
- name
- appearsIn
- friends {
- name
- }
- }
- //========================== Variables ===========================
- // You can pass variables recieved from the client to the execution engine by using the Inputs property
- // Here is what a query looks like with a variable:
- query DroidQuery($droidId: String!) {
- droid(id: $droidId) {
- id
- name
- }
- }
- // Here is what this query would look like as a JSON request:
- {
- "query": "query DroidQuery($droidId: String!) { droid(id: $droidId) { id name } }",
- "variables": {
- "droidId": "1"
- }
- }
- // Call .ToInputs() to translate JSON variables into a format that the library can work with
- var variablesJson = // get from request
- // `ToInputs` extension method converts the json to the `Inputs` class
- var inputs = variablesJson.ToInputs();
- schema.Execute(_ =>
- {
- _.Query = "...";
- _.Inputs = inputs;
- });
- //========================== Directives ==========================
- // Directive can be attached to a field or fragment inclusion and can affect execution of the query in any way the server desires
- // The core GraphQL specification includes exactly two directives.
- // - include(if: Boolean) Only include this field in the result if the argument is true.
- // - skip(if: Boolean) Skip this field if the argument is true.
- query HeroQuery($id: ID, $withFriends: Boolean!) {
- hero(id: $id) {
- name
- friends @include(if: $withFriends) {
- name
- }
- }
- }
- //========================== Mutations ===========================
- // Для использования mutation нужен рутовый объект Mutation типа ObjectGraphType
- // Mutations модифицирует данные и возвращает результат
- // Может быть только один рутовый объект Mutation
- // Выполняются последовательно
- // Вместо слова 'query' нужно использовать 'mutation'
- // Как с query, если иммется всего одна операция, ее имя можно не писать
- mutation ($human:HumanInput!) {
- createHuman(human: $human) {
- id
- name
- }
- }
- // C# class
- public class Human
- {
- public string Name { get; set; }
- public string HomePlanet { get; set; }
- }
- // Set the Mutation property on your Schema
- public class StarWarsSchema : Schema
- {
- public StarWarsSchema(IDependencyResolver resolver)
- : base(resolver)
- {
- Query = resolver.Resolve<StarWarsQuery>();
- Mutation = resolver.Resolve<StarWarsMutation>();
- }
- }
- // A mutation GraphType looks identical to a query GraphType. The difference is you are allowed to mutate data
- public class StarWarsMutation : ObjectGraphType
- {
- public StarWarsMutation(StarWarsData data)
- {
- Field<HumanType>(
- "createHuman",
- arguments: new QueryArguments(
- new QueryArgument<NonNullGraphType<HumanInputType>> {Name = "human"}
- ),
- resolve: context =>
- {
- var human = context.GetArgument<Human>("human");
- return data.AddHuman(human);
- });
- }
- }
- // Чтобы предоставить набор входных значений, нужно использовать InputObjectGraphType
- public class HumanInputType : InputObjectGraphType
- {
- public HumanInputType()
- {
- Name = "HumanInput";
- Field<NonNullGraphType<StringGraphType>>("name");
- Field<StringGraphType>("homePlanet");
- }
- }
- // StarWarsData is an in-memory data store
- public class StarWarsData
- {
- private List<Human> _humans = new List<Human>();
- public Human AddHuman(Human human)
- {
- human.Id = Guid.NewGuid().ToString();
- _humans.Add(human);
- return human;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement