In this article, I’m going to show the required pieces to put together a production-ready GraphQL Server from scratch in Ruby by reusing the open source GraphQL gem and Rack, a modular Ruby web server interface. Why Rack? In Ruby-land, can be compared to Node.js’ excellent web server. However, its approach is a little bit different. While Express is a full web server, Rack only gives you the building blocks to roll your own. Since most Ruby web servers are built on Rack, we can use them to power our GraphQL server in no time. Rack express Rack applications In Rack, like most web servers, you deal with web requests and responses. The request is the information incoming from the web browser (URL, User Agent, cookies, parameters) and the response is what the web server sends back to the browser (status, headers, HTML, JSON). The simplest Rack application simply receives a request and returns a response. app = Proc.new ['200', {'Content-Type' end The Proc defines a new block of code to execute when the server receives a request and wraps its information in the parameter. The block returns an array with 3 items: the HTTP status code, the response headers and the response body. env Rack offers multiple ways to run your application. It offers a basic development server called but because Rack is modular, you can replace the runtime by any production-ready Ruby web server implementing the Rack interface like . rackup Thin gem install thinthin start Yes, it’s that simple! Building the server Based on the concepts mentioned above, let’s build the skeleton of our server. require 'rack' class GraphQLServerdef initialize(schema:, context: {}) = schema = contextend @schema @context def response(status: 200, response)[200,{'Content-Type' => 'application/json','Content-Length' => response.bytesize.to_s},[response]]end def call(env)request = Rack::Request.new(env)response(200, "")endend The method takes a GraphQL schema as a parameter and a context object that we will pass to the schema resolvers at runtime. Have a look at the for more information on how to build your schema. I also provide an example toward the end of this article. initialize GraphQL gem The method is called for each request by Rack but it doesn’t do much for now. call I decided to extract the in its own method to simplify the method that we will work on below. response call Extracting the payload The can pass a payload using both GET and POST request types. When using GET, the payload is located in the request parameters and when using POST, it’s in the request body. GraphQL HTTP protocol We add a conditional to extract the payload according to the request type like this: def call(env)request = Rack::Request.new(env) payload = if request.get?request.paramselsif request.post?body = request.body.readJSON.parse(body)end response(200, "")end Processing a GraphQL request In the , a request consists of 3 objects: the query, its variables and the operation name. Since we already parsed the payload and the schema (from the constructor), we just have to pass these parameters to the method. GraphQL HTTP protocol schema.execute def call(env)request = Rack::Request.new(env) payload = if request.get?request.paramselsif request.post?body = request.body.readJSON.parse(body)end result = @schema .execute(payload['query'],variables: payload['variables'],operation_name: payload['operationName'],context: @context ,).to_json response(200, )end result That’s it! You now have a spec-compliant GraphQL server in Ruby. Using your new GraphQL Server You can start using your Rack server with any schema built with the GraphQL gem and serve it with your favourite Ruby web server. require 'graphql' type_def = <<-GRAPHQLtype Query {hello: String}GRAPHQL resolver = {"Query" => {"hello" => Proc.new { "world" }}} schema = GraphQL::Schema.from_definition(type_def,default_resolve: resolver) run GraphQLServer.new(schema: schema) I haven’t covered the directive yet but it simply allows Rack to use your server for all incoming requests. run What’s next? This is a very simple and naive implementation but it works with any spec-compliant GraphQL client like Apollo. However, if you want more flexibility and some error handling, you can use my open source gem which this article is based on. graphql-server If you like this kind of stuff, follow me on Medium and on . Twitter @betaflag