Class: Agoo::GraphQL

Inherits:
Object
  • Object
show all
Defined in:
ext/agoo/rgraphql.c

Class Method Summary collapse

Class Method Details

.load(sdl) ⇒ Object

call-seq: load(sdl)

Load an SDL string. This should only be called in a block provided to a call to #schema.



650
651
652
653
654
655
656
657
658
659
660
661
662
# File 'ext/agoo/rgraphql.c', line 650

static VALUE
graphql_load(VALUE self, VALUE sdl) {
    struct _agooErr	err = AGOO_ERR_INIT;

    if (NULL == gql_root) {
	rb_raise(rb_eStandardError, "GraphQL root not set. Use Agoo::GraphQL.schema.");
    }
    rb_check_type(sdl, T_STRING);
    if (AGOO_ERR_OK != sdl_parse(&err, StringValuePtr(sdl), RSTRING_LEN(sdl))) {
	rb_raise(rb_eStandardError, "%s", err.msg);
    }
    return Qnil;
}

.load_file(path) ⇒ Object

call-seq: load_file(sdl_file)

Load an SDL file. This should only be called in a block provided to a call to #schema.



671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
# File 'ext/agoo/rgraphql.c', line 671

static VALUE
graphql_load_file(VALUE self, VALUE path) {
    struct _agooErr	err = AGOO_ERR_INIT;
    FILE		*f;
    long		len;
    char		*sdl;

    if (NULL == gql_root) {
	rb_raise(rb_eStandardError, "GraphQL root not set. Use Agoo::GraphQL.schema.");
    }
    rb_check_type(path, T_STRING);
    if (NULL == (f = fopen(StringValuePtr(path), "r"))) {
	rb_raise(rb_eIOError, "%s", strerror(errno));
    }
    if (0 != fseek(f, 0, SEEK_END)) {
	rb_raise(rb_eIOError, "%s", strerror(errno));
    }
    if (0 > (len = ftell(f))) {
	rb_raise(rb_eIOError, "%s", strerror(errno));
    }
    sdl = ALLOC_N(char, len + 1);
    if (0 != fseek(f, 0, SEEK_SET)) {
	rb_raise(rb_eIOError, "%s", strerror(errno));
    }
    if (len != (long)fread(sdl, 1, len, f)) {
	rb_raise(rb_eIOError, "%s", strerror(errno));
    } else {
	sdl[len] = '\0';
    }
    fclose(f);
    if (AGOO_ERR_OK != sdl_parse(&err, sdl, len)) {
	xfree(sdl);
	rb_raise(rb_eStandardError, "%s", err.msg);
    }
    xfree(sdl);

    return Qnil;
}

.schema(root) ⇒ Object

call-seq: schema(root) { }

Start the GraphQL/Ruby integration by assigning a root Ruby object to the GraphQL environment. Within the block passed to the function SDL strings or files can be loaded. On exiting the block validation of the loaded schema is performed.

Note that the _@ruby_ directive is added to the schema type as well as the Query, Mutation, and Subscription types based on the root class. Any _@ruby_ directives on the object types in the SDL will also associate a GraphQL and Ruby class. The association will be used to validate the Ruby class as a way to verify the class implements the methods described by the GraphQL type. The association is also use for resolving



570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
# File 'ext/agoo/rgraphql.c', line 570

static VALUE
graphql_schema(VALUE self, VALUE root) {
    struct _agooErr	err = AGOO_ERR_INIT;
    gqlDir		dir;
    gqlDirUse		use;
    gqlType		schema_type;
    bool		fresh = false;

    if (!rb_block_given_p()) {
	rb_raise(rb_eStandardError, "A block is required.");
    }
    if (AGOO_ERR_OK != gql_init(&err)) {
	printf("*-*-* %s\n", err.msg);
	exit(1);
    }
    if (NULL == (dir = gql_directive_create(&err, "ruby", "Associates a Ruby class with a GraphQL type.", 0))) {
	printf("*-*-* %s\n", err.msg);
	exit(2);
    }
    if (NULL == gql_dir_arg(&err, dir, "class", &gql_string_type, NULL, 0, NULL, true)) {
	printf("*-*-* %s\n", err.msg);
	exit(3);
    }
    if (AGOO_ERR_OK != gql_directive_on(&err, dir, "SCHEMA", 6) ||
	AGOO_ERR_OK != gql_directive_on(&err, dir, "OBJECT", 6)) {
	printf("*-*-* %s\n", err.msg);
	exit(4);
    }
    gql_root = (gqlRef)root;
    vroot = root;
    rb_gc_register_address(&vroot);

    gql_doc_eval_func = eval_wrap;
    gql_resolve_func = resolve;
    gql_type_func = ref_type;
    gql_root_op = root_op;

    if (NULL == (use = gql_dir_use_create(&err, "ruby"))) {
	printf("*-*-* %s\n", err.msg);
	exit(5);
    }
    if (AGOO_ERR_OK != gql_dir_use_arg(&err, use, "class", gql_string_create(&err, rb_obj_classname(root), 0))) {
	printf("*-*-* %s\n", err.msg);
	exit(6);
    }
    rb_rescue2(rescue_yield, Qnil, rescue_yield_error, (VALUE)&err, rb_eException, 0);
    if (AGOO_ERR_OK != err.code) {
	printf("*-*-* %s\n", err.msg);
	exit(7);
    }
    if (NULL == (schema_type = gql_type_get("schema"))) {
	if (NULL == (schema_type = gql_schema_create(&err, "The GraphQL root Object.", 0))) {
	    printf("*-*-* %s\n", err.msg);
	    exit(8);
	}
	fresh = true;
    }

    if (AGOO_ERR_OK != gql_type_directive_use(&err, schema_type, use) ||
	AGOO_ERR_OK != make_ruby_use(&err, root, "query", "Query", fresh, schema_type, "Root level query.") ||
	AGOO_ERR_OK != make_ruby_use(&err, root, "mutation", "Mutation", fresh, schema_type, "Root level mutation.") ||
	AGOO_ERR_OK != make_ruby_use(&err, root, "subscription", "Subscription", fresh, schema_type, "Root level subscription.")) {
	printf("*-*-* %s\n", err.msg);
	exit(9);
    }
    if (AGOO_ERR_OK != gql_validate(&err) ||
	AGOO_ERR_OK != build_type_class_map(&err)) {
	printf("*-*-* %s\n", err.msg);
	exit(10);
    }
    return Qnil;
}

.sdl_dump(options) ⇒ Object

call-seq: dump_sdl()

The preferred method of inspecting a GraphQL schema is to use introspection queries but for debugging and for reviewing the schema a dump of the schema as SDL can be helpful. The #dump_sdl method returns the schema as an SDL string.

  • options [Hash] server options

    • :with_description [true|false] if true the description strings are included. If false they are not included.

    • :all [true|false] if true all types and directives are included in the dump. If false only the user created types are include.



726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
# File 'ext/agoo/rgraphql.c', line 726

static VALUE
graphql_sdl_dump(VALUE self, VALUE options) {
    agooText		t = agoo_text_allocate(4096);
    volatile VALUE	dump;
    VALUE		v;
    bool		with_desc = true;
    bool		all = false;

    Check_Type(options, T_HASH);

    v = rb_hash_aref(options, ID2SYM(rb_intern("with_descriptions")));
    if (Qnil != v) {
	with_desc = (Qtrue == v);
    }
    v = rb_hash_aref(options, ID2SYM(rb_intern("all")));
    if (Qnil != v) {
	all = (Qtrue == v);
    }
    if (NULL == (t = gql_schema_sdl(t, with_desc, all))) {
	rb_raise(rb_eNoMemError, "Failed to allocate memory for a schema dump.");
    }
    dump = rb_str_new(t->text, t->len);
    agoo_text_release(t);

    return dump;
}