Advertisement
Guest User

Untitled

a guest
Oct 20th, 2019
144
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.03 KB | None | 0 0
  1. Introduction
  2. Queries
  3. Data Types
  4. Lists and Non-Null
  5. Arguments
  6. Aliases
  7. Fragments
  8. Variables
  9. Directives
  10. Mutations
  11.  
  12. //========================= Introduction =========================
  13. // Here is a "Hello World" example for GraphQL .NET.
  14.  
  15. using System;
  16. using GraphQL;
  17. using GraphQL.Types;
  18.  
  19. public class Program
  20. {
  21. public static void Main(string[] args)
  22. {
  23. var schema = Schema.For(@"
  24. type Query {
  25. hello: String
  26. }
  27. ");
  28.  
  29. var json = schema.Execute(_ =>
  30. {
  31. _.Query = "{ hello }";
  32. _.Root = new { Hello = "Hello World!" };
  33. });
  34.  
  35. Console.WriteLine(json);
  36. }
  37. }
  38.  
  39. // Output
  40. {
  41. "data": {
  42. "hello": "Hello World!"
  43. }
  44. }
  45.  
  46. // Пример
  47. type Droid {
  48. id: String!
  49. name: String!
  50. }
  51.  
  52. type Query {
  53. hero: Droid
  54. }
  55.  
  56. // Schema First Approach
  57. public class Droid
  58. {
  59. public string Id { get; set; }
  60. public string Name { get; set; }
  61. }
  62.  
  63. public class Query
  64. {
  65. [GraphQLMetadata("hero")]
  66. public Droid GetHero()
  67. {
  68. return new Droid { Id = "1", Name = "R2-D2" };
  69. }
  70. }
  71.  
  72. var schema = Schema.For(@"
  73. type Droid {
  74. id: String!
  75. name: String!
  76. }
  77.  
  78. type Query {
  79. hero: Droid
  80. }
  81. ", _ => {
  82. _.Types.Include<Query>();
  83. });
  84.  
  85. var json = schema.Execute(_ =>
  86. {
  87. _.Query = "{ hero { id name } }";
  88. });
  89.  
  90. // Output
  91. {
  92. "data": {
  93. "hero": {
  94. "id": "1",
  95. "name": "R2-D2"
  96. }
  97. }
  98. }
  99.  
  100. // GraphType First Approach
  101. using System;
  102. using GraphQL;
  103. using GraphQL.Types;
  104.  
  105. public class Droid
  106. {
  107. public string Id { get; set; }
  108. public string Name { get; set; }
  109. }
  110.  
  111. public class DroidType : ObjectGraphType<Droid>
  112. {
  113. public DroidType()
  114. {
  115. Field(x => x.Id).Description("The Id of the Droid.");
  116. Field(x => x.Name).Description("The name of the Droid.");
  117. }
  118. }
  119.  
  120. public class StarWarsQuery : ObjectGraphType
  121. {
  122. public StarWarsQuery()
  123. {
  124. Field<DroidType>(
  125. "hero",
  126. resolve: context => new Droid { Id = "1", Name = "R2-D2" }
  127. );
  128. }
  129. }
  130.  
  131. public class Program
  132. {
  133. public static void Main(string[] args)
  134. {
  135. var schema = new Schema { Query = new StarWarsQuery() };
  136.  
  137. var json = schema.Execute(_ =>
  138. {
  139. _.Query = "{ hero { id name } }";
  140. });
  141.  
  142. Console.WriteLine(json);
  143. }
  144. }
  145.  
  146. // Output
  147. {
  148. "data": {
  149. "hero": {
  150. "id": "1",
  151. "name": "R2-D2"
  152. }
  153. }
  154. }
  155.  
  156. // Schema First Nested Types
  157. public class Droid
  158. {
  159. public string Id { get; set; }
  160. public string Name { get; set; }
  161. }
  162.  
  163. public class Character
  164. {
  165. public string Name { get; set; }
  166. }
  167.  
  168. public class Query
  169. {
  170. [GraphQLMetadata("hero")]
  171. public Droid GetHero()
  172. {
  173. return new Droid { Id = "1", Name = "R2-D2" };
  174. }
  175. }
  176.  
  177. [GraphQLMetadata("Droid", IsTypeOf=typeof(Droid))]
  178. public class DroidType
  179. {
  180. public string Id(Droid droid) => droid.Id;
  181. public string Name(Droid droid) => droid.Name;
  182.  
  183. // these two parameters are optional
  184. // ResolveFieldContext provides contextual information about the field
  185. public Character Friend(ResolveFieldContext context, Droid source)
  186. {
  187. return new Character { Name = "C3-PO" };
  188. }
  189. }
  190.  
  191. var schema = Schema.For(@"
  192. type Droid {
  193. id: String!
  194. name: String!
  195. friend: Character
  196. }
  197.  
  198. type Character {
  199. name: String!
  200. }
  201.  
  202. type Query {
  203. hero: Droid
  204. }
  205. ", _ => {
  206. _.Types.Include<DroidType>();
  207. _.Types.Include<Query>();
  208. });
  209.  
  210. var json = schema.Execute(_ =>
  211. {
  212. _.Query = "{ hero { id name friend { name } } }";
  213. });
  214.  
  215. // Output
  216. {
  217. "data": {
  218. "hero": {
  219. "id": "1",
  220. "name": "R2-D2",
  221. "friend": {
  222. "name": "C3-PO"
  223. }
  224. }
  225. }
  226. }
  227.  
  228. //=========================== Queries ============================
  229. // To perform a query you need to have a root Query object that is an ObjectGraphType
  230. // Queries should only fetch data and never modify it. You can only have a single root Query object
  231. // Queries are executed in parallel
  232. query {
  233. hero {
  234. id
  235. name
  236. }
  237. }
  238.  
  239. // If you have only a single query, you can use shorthand syntax
  240. hero {
  241. id
  242. name
  243. }
  244.  
  245. // To provide an Operation name for your query, you add it after the query keyword
  246. // An Operation name is optional if there is only a single operation in the request
  247. query MyHeroQuery {
  248. hero {
  249. id
  250. name
  251. }
  252. }
  253.  
  254. // You can also provide that operation name to the ExecutionOptions
  255. var schema = new Schema { Query = new StarWarsQuery() };
  256. var json = schema.Execute(_ =>
  257. {
  258. _.OperationName = "MyHeroQuery";
  259. _.Query = @"
  260. query MyHeroQuery {
  261. hero {
  262. id
  263. name
  264. }
  265. }
  266. ";
  267. });
  268.  
  269. public class StarWarsQuery : ObjectGraphType
  270. {
  271. public StarWarsQuery()
  272. {
  273. Field<DroidType>(
  274. "hero",
  275. resolve: context => new Droid { Id = "1", Name = "R2-D2" }
  276. );
  277. }
  278. }
  279.  
  280. //========================== Data Types ==========================
  281. // Простые - String, Int, Float, Boolean, ID
  282.  
  283. // OBJECTS
  284. // GraphQL
  285. type Droid {
  286. name: String
  287. appearsIn: [Episode]
  288. }
  289.  
  290. // GraphQL .NET
  291. public class DroidType : ObjectGraphType<Droid>
  292. {
  293. public DroidType()
  294. {
  295. Name = "Droid";
  296. Description = "A mechanical creature in the Star Wars universe.";
  297. Field(d => d.Name, nullable: true).Description("The name of the droid.");
  298. Field<ListGraphType<EpisodeEnum>>("appearsIn", "Which movie they appear in.");
  299. }
  300. }
  301.  
  302. // .NET
  303. public class Droid
  304. {
  305. public string Name { get; set; }
  306. public List<Episode> AppearsIn { get; set; }
  307. }
  308.  
  309. // ENUMERATIONS
  310. // GraphQL
  311. enum Episode {
  312. NEWHOPE
  313. EMPIRE
  314. JEDI
  315. }
  316.  
  317. // GraphQL .NET
  318. // You can manually create the EnumerationGraphType
  319. public class EpisodeEnum : EnumerationGraphType
  320. {
  321. public EpisodeEnum()
  322. {
  323. Name = "Episode";
  324. Description = "One of the films in the Star Wars Trilogy.";
  325. AddValue("NEWHOPE", "Released in 1977.", 4);
  326. AddValue("EMPIRE", "Released in 1980.", 5);
  327. AddValue("JEDI", "Released in 1983.", 6);
  328. }
  329. }
  330.  
  331. // Or you can use the generic version passing it a .NET enum which will populate the values for you (excluding description)
  332. // The Name will default to the .NET Type name, which you can override in the constructor
  333. public class EpisodeEnum : EnumerationGraphType<Episodes>
  334. {
  335. }
  336.  
  337. // .NET
  338. public enum Episodes
  339. {
  340. NEWHOPE = 4,
  341. EMPIRE = 5,
  342. JEDI = 6
  343. }
  344.  
  345. //====================== Lists and Non-Null ======================
  346. // Object types, scalars, and enums are the only kinds of types you can define in GraphQL
  347. // But when you use the types in other parts of the schema, or in your query variable declarations, you can apply
  348. // additional type modifiers that affect validation of those values. Let's look at an example:
  349. type Character {
  350. name: String!
  351. appearsIn: [Episode]!
  352. }
  353.  
  354. // Here, we're using a String type and marking it as Non-Null by adding an exclamation mark, ! after the type name
  355. // This means that our server always expects to return a non-null value for this field, and if it ends up getting a null
  356. // value that will actually trigger a GraphQL execution error, letting the client know that something has gone wrong
  357.  
  358. // The Non-Null type modifier can also be used when defining arguments for a field, which will cause the GraphQL server
  359. // to return a validation error if a null value is passed as that argument, whether in the GraphQL string or in the variables
  360. query DroidById($id: ID!) {
  361. droid(id: $id) {
  362. name
  363. }
  364. }
  365.  
  366. // 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
  367. // return an array of that type. In the schema language, this is denoted by wrapping the type in square brackets, [ and ]
  368. // It works the same for arguments, where the validation step will expect an array for that value
  369.  
  370. // The Non-Null and List modifiers can be combined. For example, you can have a List of Non-Null Strings:
  371. myField: [String!]
  372.  
  373. // This means that the list itself can be null, but it can't have any null members. For example, in JSON:
  374. myField: null // valid
  375. myField: [] // valid
  376. myField: ['a', 'b'] // valid
  377. myField: ['a', null, 'b'] // error
  378. Now, let's say we defined a Non-Null List of Strings:
  379.  
  380. myField: [String]!
  381.  
  382. // This means that the list itself cannot be null, but it can contain null values:
  383. myField: null // error
  384. myField: [] // valid
  385. myField: ['a', 'b'] // valid
  386. myField: ['a', null, 'b'] // valid
  387.  
  388. // You can arbitrarily nest any number of Non-Null and List modifiers, according to your needs
  389.  
  390. //=========================== Arguments ==========================
  391. // You can provide arguments to a field. You can use GetArgument on ResolveFieldContext to retrieve argument values
  392. // GetArgument will attempt to coerce the argument values to the generic type it is given, including primitive values,
  393. // objects, and enumerations. You can gain access to the value directly through the Arguments dictionary on ResolveFieldContext
  394. query {
  395. droid(id: "123") {
  396. id
  397. name
  398. }
  399. }
  400.  
  401. // Schema First
  402. public class Droid
  403. {
  404. public string Id { get; set; }
  405. public string Name { get; set; }
  406. }
  407.  
  408. public class Query
  409. {
  410. private List<Droid> _droids = new List<Droid>
  411. {
  412. new Droid { Id = "123", Name = "R2-D2" }
  413. };
  414.  
  415. [GraphQLMetadata("droid")]
  416. public Droid GetDroid(string id)
  417. {
  418. return _droids.FirstOrDefault(x => x.Id == id);
  419. }
  420. }
  421.  
  422. var schema = Schema.For(@"
  423. type Droid {
  424. id: ID!
  425. name: String
  426. }
  427.  
  428. type Query {
  429. droid(id: ID!): Droid
  430. }
  431. ", _ => {
  432. _.Types.Include<Query>();
  433. });
  434.  
  435. var json = schema.Execute(_ =>
  436. {
  437. _.Query = $"{{ droid(id: \"123\") {{ id name }} }}";
  438. });
  439.  
  440. // GraphType First
  441. public class Droid
  442. {
  443. public string Id { get; set; }
  444. public string Name { get; set; }
  445. }
  446.  
  447. public class DroidType : ObjectGraphType
  448. {
  449. public DroidType()
  450. {
  451. Field<NonNullGraphType<IdGraphType>>("id");
  452. Field<StringGraphType>("name");
  453. }
  454. }
  455.  
  456. public class StarWarsQuery : ObjectGraphType
  457. {
  458. private List<Droid> _droids = new List<Droid>
  459. {
  460. new Droid { Id = "123", Name = "R2-D2" }
  461. };
  462.  
  463. public StarWarsQuery()
  464. {
  465. Field<DroidType>(
  466. "droid",
  467. arguments: new QueryArguments(
  468. new QueryArgument<IdGraphType> { Name = "id" }
  469. ),
  470. resolve: context =>
  471. {
  472. var id = context.GetArgument<string>("id");
  473. return _droids.FirstOrDefault(x => x.Id == id);
  474. }
  475. );
  476. }
  477. }
  478.  
  479. var schema = new Schema { Query = new StarWarsQuery() };
  480. var json = schema.Execute(_ =>
  481. {
  482. _.Query = $"{{ droid(id: \"123\") {{ id name }} }}";
  483. })
  484.  
  485. //============================ Aliases ===========================
  486. {
  487. empireHero: hero(id: "1") {
  488. name
  489. }
  490. jediHero: hero(id: "2") {
  491. name
  492. }
  493. }
  494.  
  495. //=========================== Fragments ==========================
  496. // Fragments let you construct sets of fields and then include them in queries where you need to.
  497. query {
  498. leftComparison: hero(id: "1") {
  499. ...comparisonFields
  500. }
  501. rightComparison: hero(id: "2") {
  502. ...comparisonFields
  503. }
  504. }
  505.  
  506. fragment comparisonFields on Character {
  507. name
  508. appearsIn
  509. friends {
  510. name
  511. }
  512. }
  513.  
  514. //========================== Variables ===========================
  515. // You can pass variables recieved from the client to the execution engine by using the Inputs property
  516. // Here is what a query looks like with a variable:
  517. query DroidQuery($droidId: String!) {
  518. droid(id: $droidId) {
  519. id
  520. name
  521. }
  522. }
  523.  
  524. // Here is what this query would look like as a JSON request:
  525. {
  526. "query": "query DroidQuery($droidId: String!) { droid(id: $droidId) { id name } }",
  527. "variables": {
  528. "droidId": "1"
  529. }
  530. }
  531.  
  532. // Call .ToInputs() to translate JSON variables into a format that the library can work with
  533. var variablesJson = // get from request
  534. // `ToInputs` extension method converts the json to the `Inputs` class
  535. var inputs = variablesJson.ToInputs();
  536. schema.Execute(_ =>
  537. {
  538. _.Query = "...";
  539. _.Inputs = inputs;
  540. });
  541.  
  542. //========================== Directives ==========================
  543. // Directive can be attached to a field or fragment inclusion and can affect execution of the query in any way the server desires
  544. // The core GraphQL specification includes exactly two directives.
  545. // - include(if: Boolean) Only include this field in the result if the argument is true.
  546. // - skip(if: Boolean) Skip this field if the argument is true.
  547. query HeroQuery($id: ID, $withFriends: Boolean!) {
  548. hero(id: $id) {
  549. name
  550. friends @include(if: $withFriends) {
  551. name
  552. }
  553. }
  554. }
  555.  
  556. //========================== Mutations ===========================
  557. // Для использования mutation нужен рутовый объект Mutation типа ObjectGraphType
  558. // Mutations модифицирует данные и возвращает результат
  559. // Может быть только один рутовый объект Mutation
  560. // Выполняются последовательно
  561. // Вместо слова 'query' нужно использовать 'mutation'
  562. // Как с query, если иммется всего одна операция, ее имя можно не писать
  563. mutation ($human:HumanInput!) {
  564. createHuman(human: $human) {
  565. id
  566. name
  567. }
  568. }
  569.  
  570. // C# class
  571. public class Human
  572. {
  573. public string Name { get; set; }
  574. public string HomePlanet { get; set; }
  575. }
  576.  
  577. // Set the Mutation property on your Schema
  578. public class StarWarsSchema : Schema
  579. {
  580. public StarWarsSchema(IDependencyResolver resolver)
  581. : base(resolver)
  582. {
  583. Query = resolver.Resolve<StarWarsQuery>();
  584. Mutation = resolver.Resolve<StarWarsMutation>();
  585. }
  586. }
  587.  
  588. // A mutation GraphType looks identical to a query GraphType. The difference is you are allowed to mutate data
  589. public class StarWarsMutation : ObjectGraphType
  590. {
  591. public StarWarsMutation(StarWarsData data)
  592. {
  593. Field<HumanType>(
  594. "createHuman",
  595. arguments: new QueryArguments(
  596. new QueryArgument<NonNullGraphType<HumanInputType>> {Name = "human"}
  597. ),
  598. resolve: context =>
  599. {
  600. var human = context.GetArgument<Human>("human");
  601. return data.AddHuman(human);
  602. });
  603. }
  604. }
  605.  
  606. // Чтобы предоставить набор входных значений, нужно использовать InputObjectGraphType
  607. public class HumanInputType : InputObjectGraphType
  608. {
  609. public HumanInputType()
  610. {
  611. Name = "HumanInput";
  612. Field<NonNullGraphType<StringGraphType>>("name");
  613. Field<StringGraphType>("homePlanet");
  614. }
  615. }
  616.  
  617. // StarWarsData is an in-memory data store
  618. public class StarWarsData
  619. {
  620. private List<Human> _humans = new List<Human>();
  621.  
  622. public Human AddHuman(Human human)
  623. {
  624. human.Id = Guid.NewGuid().ToString();
  625. _humans.Add(human);
  626. return human;
  627. }
  628. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement