├── .gitignore ├── .merlin ├── Makefile ├── README.md ├── _oasis ├── _tags ├── configure ├── setup.ml └── src ├── lib ├── graphql.ml └── graphql_stubs.c └── server └── main.ml /.gitignore: -------------------------------------------------------------------------------- 1 | _build 2 | *.native 3 | *.byte 4 | *.docdir 5 | META 6 | *.mldylib 7 | *.mllib 8 | *.clib 9 | 10 | tests/*.cmi 11 | tests/*.cmt 12 | tests/*.cmo 13 | tests/*.cma 14 | 15 | setup.data 16 | setup.log 17 | README.org 18 | scratch 19 | notes.txt 20 | dump_stats.ml 21 | scratch.c 22 | T 23 | scratch.cpp 24 | myocamlbuild.ml 25 | api.odocl 26 | brotli.0.1 27 | alice29.txt 28 | -------------------------------------------------------------------------------- /.merlin: -------------------------------------------------------------------------------- 1 | B _build/src/lib 2 | PKG lwt.unix lwt.ppx graphql yojson 3 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # OASIS_START 2 | # DO NOT EDIT (digest: a3c674b4239234cbbe53afe090018954) 3 | 4 | SETUP = ocaml setup.ml 5 | 6 | build: setup.data 7 | $(SETUP) -build $(BUILDFLAGS) 8 | 9 | doc: setup.data build 10 | $(SETUP) -doc $(DOCFLAGS) 11 | 12 | test: setup.data build 13 | $(SETUP) -test $(TESTFLAGS) 14 | 15 | all: 16 | $(SETUP) -all $(ALLFLAGS) 17 | 18 | install: setup.data 19 | $(SETUP) -install $(INSTALLFLAGS) 20 | 21 | uninstall: setup.data 22 | $(SETUP) -uninstall $(UNINSTALLFLAGS) 23 | 24 | reinstall: setup.data 25 | $(SETUP) -reinstall $(REINSTALLFLAGS) 26 | 27 | clean: 28 | $(SETUP) -clean $(CLEANFLAGS) 29 | 30 | distclean: 31 | $(SETUP) -distclean $(DISTCLEANFLAGS) 32 | 33 | setup.data: 34 | $(SETUP) -configure $(CONFIGUREFLAGS) 35 | 36 | configure: 37 | $(SETUP) -configure $(CONFIGUREFLAGS) 38 | 39 | .PHONY: build doc test all install uninstall reinstall clean distclean configure 40 | 41 | # OASIS_STOP 42 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Graphql, typesafe and fast 2 | 3 | OCaml implementation of graphql, created with speed and correctness in 4 | mind. Uses Facebook's own `libgraphqlparser` for raw C++ parsing speed. 5 | 6 | TODO: 7 | 8 | 1) Functorize backend, start with postgres 9 | 2) Error handle everywhere please 10 | 3) Use bigstring/bigarray instead of copying over and over 11 | 4) Provide concurrent server 12 | -------------------------------------------------------------------------------- /_oasis: -------------------------------------------------------------------------------- 1 | # -*- conf -*- 2 | OASISFormat: 0.4 3 | OCamlVersion: >= 4.02.3 4 | Name: graphql 5 | Version: 0.0.1 6 | Maintainers: Edgar Aroutiounian 7 | Homepage: http://hyegar.com 8 | Synopsis: Graphql implementation in OCaml 9 | Authors: Edgar Aroutiounian 10 | License: BSD-3-clause 11 | Plugins: META (0.4), DevFiles (0.4) 12 | AlphaFeatures: ocamlbuild_more_args 13 | 14 | # PreBuildCommand: 15 | # sh prepare.sh 16 | 17 | Description: 18 | OCaml implementation of Graphql 19 | 20 | Executable graphql_server 21 | Path: src/server 22 | BuildTools:ocamlbuild 23 | install: true 24 | MainIs: main.ml 25 | CompiledObject: native 26 | # Might use brotli, need to fix it. 27 | BuildDepends: cmdliner, graphql 28 | 29 | Library graphql 30 | Path: src/lib 31 | BuildTools:ocamlbuild 32 | install: true 33 | CClib: -L/usr/local/lib -lgraphqlparser -lstdc++ 34 | CCOpt: -g -Wall -std=c++11 -x c++ -I/usr/local/include 35 | NativeOpt: -cc clang++ 36 | ByteOpt: -cc clang++ 37 | Modules: Graphql 38 | # InternalModules: 39 | CompiledObject: native 40 | CSources: graphql_stubs.c 41 | BuildDepends: lwt.unix, lwt.ppx, bigstring, yojson, postgresql 42 | 43 | Document api 44 | Title: API reference for graphql 45 | Type: ocamlbuild (0.4) 46 | Authors: Edgar Aroutiounian 47 | BuildTools: ocamldoc, ocamlbuild 48 | Format: HTML 49 | Index: index.html 50 | XOCamlbuildPath: . 51 | XOCamlbuildLibraries: graphql 52 | -------------------------------------------------------------------------------- /_tags: -------------------------------------------------------------------------------- 1 | # OASIS_START 2 | # DO NOT EDIT (digest: 8e5a9a387583a6700908668923066cd2) 3 | # Ignore VCS directories, you can use the same kind of rule outside 4 | # OASIS_START/STOP if you want to exclude directories that contains 5 | # useless stuff for the build process 6 | true: annot, bin_annot 7 | <**/.svn>: -traverse 8 | <**/.svn>: not_hygienic 9 | ".bzr": -traverse 10 | ".bzr": not_hygienic 11 | ".hg": -traverse 12 | ".hg": not_hygienic 13 | ".git": -traverse 14 | ".git": not_hygienic 15 | "_darcs": -traverse 16 | "_darcs": not_hygienic 17 | # Library graphql 18 | "src/graphql.cmxs": use_graphql 19 | : oasis_library_graphql_ccopt 20 | "src/graphql_stubs.c": oasis_library_graphql_ccopt 21 | "src/graphql.cmxa": oasis_library_graphql_cclib 22 | "src/libgraphql_stubs.lib": oasis_library_graphql_cclib 23 | "src/dllgraphql_stubs.dll": oasis_library_graphql_cclib 24 | "src/libgraphql_stubs.a": oasis_library_graphql_cclib 25 | "src/dllgraphql_stubs.so": oasis_library_graphql_cclib 26 | "src/graphql.cmxa": oasis_library_graphql_byte 27 | : oasis_library_graphql_byte 28 | "src/graphql_stubs.c": oasis_library_graphql_byte 29 | "src/graphql.cmxa": oasis_library_graphql_native 30 | : oasis_library_graphql_native 31 | "src/graphql_stubs.c": oasis_library_graphql_native 32 | "src/graphql.cmxa": use_libgraphql_stubs 33 | : package(lwt.ppx) 34 | : package(lwt.unix) 35 | "src/graphql_stubs.c": package(lwt.ppx) 36 | "src/graphql_stubs.c": package(lwt.unix) 37 | # OASIS_STOP 38 | # crucial that this comes after oasis_stop 39 | true: thread -------------------------------------------------------------------------------- /configure: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | # OASIS_START 4 | # DO NOT EDIT (digest: dc86c2ad450f91ca10c931b6045d0499) 5 | set -e 6 | 7 | FST=true 8 | for i in "$@"; do 9 | if $FST; then 10 | set -- 11 | FST=false 12 | fi 13 | 14 | case $i in 15 | --*=*) 16 | ARG=${i%%=*} 17 | VAL=${i##*=} 18 | set -- "$@" "$ARG" "$VAL" 19 | ;; 20 | *) 21 | set -- "$@" "$i" 22 | ;; 23 | esac 24 | done 25 | 26 | ocaml setup.ml -configure "$@" 27 | # OASIS_STOP 28 | -------------------------------------------------------------------------------- /setup.ml: -------------------------------------------------------------------------------- 1 | (* setup.ml generated for the first time by OASIS v0.4.5 *) 2 | 3 | (* OASIS_START *) 4 | (* DO NOT EDIT (digest: 9852805d5c19ca1cb6abefde2dcea323) *) 5 | (******************************************************************************) 6 | (* OASIS: architecture for building OCaml libraries and applications *) 7 | (* *) 8 | (* Copyright (C) 2011-2013, Sylvain Le Gall *) 9 | (* Copyright (C) 2008-2011, OCamlCore SARL *) 10 | (* *) 11 | (* This library is free software; you can redistribute it and/or modify it *) 12 | (* under the terms of the GNU Lesser General Public License as published by *) 13 | (* the Free Software Foundation; either version 2.1 of the License, or (at *) 14 | (* your option) any later version, with the OCaml static compilation *) 15 | (* exception. *) 16 | (* *) 17 | (* This library is distributed in the hope that it will be useful, but *) 18 | (* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *) 19 | (* or FITNESS FOR A PARTICULAR PURPOSE. See the file COPYING for more *) 20 | (* details. *) 21 | (* *) 22 | (* You should have received a copy of the GNU Lesser General Public License *) 23 | (* along with this library; if not, write to the Free Software Foundation, *) 24 | (* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA *) 25 | (******************************************************************************) 26 | 27 | let () = 28 | try 29 | Topdirs.dir_directory (Sys.getenv "OCAML_TOPLEVEL_PATH") 30 | with Not_found -> () 31 | ;; 32 | #use "topfind";; 33 | #require "oasis.dynrun";; 34 | open OASISDynRun;; 35 | 36 | (* OASIS_STOP *) 37 | let () = setup ();; 38 | -------------------------------------------------------------------------------- /src/lib/graphql.ml: -------------------------------------------------------------------------------- 1 | 2 | (* Backend should be functorized, start with Postgres *) 3 | 4 | external parse_query_raw : bytes -> bytes = "caml_parse_graphql" 5 | 6 | let parse_query = fun s -> parse_query_raw s |> Yojson.Basic.from_string 7 | -------------------------------------------------------------------------------- /src/lib/graphql_stubs.c: -------------------------------------------------------------------------------- 1 | /* -*- c++ -*- */ 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | 17 | extern "C" { 18 | 19 | CAMLprim value caml_parse_graphql(value message) 20 | { 21 | CAMLparam1(message); 22 | 23 | const char *error; 24 | 25 | const char *c_side = caml_strdup(String_val(message)); 26 | auto ast = facebook::graphql::parseString(c_side, &error); 27 | 28 | const char *json = graphql_ast_to_json((const struct GraphQLAstNode *)ast.get()); 29 | 30 | CAMLreturn(caml_copy_string(json)); 31 | } 32 | 33 | } 34 | -------------------------------------------------------------------------------- /src/server/main.ml: -------------------------------------------------------------------------------- 1 | open Graphql 2 | 3 | let test_data = "{query getHighScores(limit: 10) { score }}" 4 | 5 | let () = 6 | Graphql.parse_query test_data 7 | |> Yojson.Basic.pretty_to_string 8 | |> print_endline 9 | --------------------------------------------------------------------------------