# Mentorenwahl: A fullstack application for assigning mentors to students based on their whishes. # Copyright (C) 2022 Dominic Grimm # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation, either version 3 of the License, or # (at your option) any later version. # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # You should have received a copy of the GNU General Public License # along with this program. If not, see . require "router" require "http/server" require "json" module Backend module Api # Api webserver class WebServer include Router # GraphQL playground HTML code # # NOTE: Is minified in production GRAPHQL_PLAYGROUND = {{ flag?(:development) ? read_file("#{__DIR__}/playground.html") : run("./macros/minify_html.cr", read_file("#{__DIR__}/playground.html")).stringify }} # GraphQL request data serializer struct GraphQLQueryData include JSON::Serializable property query : String property variables : Hash(String, JSON::Any)? property operation_name : String? end # "Draws" (creates) routes def draw_routes : Nil # enable graphql playground when in development mode or explicitly enabled if Backend.config.api.graphql_playground_fully_enabled? Log.info { "GraphQL playground enabled" } get "/" do |context| context.response.content_type = "text/html" context.response.puts(GRAPHQL_PLAYGROUND) context end end post "/" do |context| context.response.content_type = "application/json" data = GraphQLQueryData.from_json(context.request.body.not_nil!.gets.not_nil!) context.response.print( Schema::SCHEMA.execute( data.query, data.variables, data.operation_name, Context.new(context.request) ) ) context end end # Runs the webserver with according middleware def run : Nil draw_routes server = HTTP::Server.new( [ HTTP::LogHandler.new, HTTP::ErrorHandler.new, HTTP::CompressHandler.new, route_handler, ] ) server.bind_tcp("0.0.0.0", 80, true) server.listen end end end end