function create_question($request, $assignment_id = null)
{
    Authenticator::assert_manager_or_professor($request->cookies['authToken']);
    $msg = new Messages($GLOBALS['locale']);
    try {
        $model = new Model();
        $raw_input = $request->getBody();
        $content_type = explode(';', $request->type)[0];
        if ($content_type !== 'application/json') {
            Util::output_errors_and_die('', 415);
        }
        $input_data = json_decode($raw_input, true);
        if (empty($input_data)) {
            Util::output_errors_and_die('', 400);
        }
        set_empty_if_undefined($input_data['type']);
        if (!Validator::validate_question_type($input_data['type'])) {
            Util::output_errors_and_die($msg->_('invalid-type'), 400);
        }
        switch ($input_data['type']) {
            case 'short-answer':
                $q = new QuestionSA($input_data, Question::FROM_USER);
                break;
            case 'essay':
                $q = new QuestionES($input_data, Question::FROM_USER);
                break;
            case 'multiple-choice':
                $q = new QuestionMC($input_data, Question::FROM_USER);
                break;
            case 'matching':
                $q = new QuestionMA($input_data, Question::FROM_USER);
                break;
            case 'fitb-type':
                $q = new QuestionFT($input_data, Question::FROM_USER);
                break;
            case 'fitb-select':
                $q = new QuestionFS($input_data, Question::FROM_USER);
                break;
            case 'source-code':
                $q = new QuestionSC($input_data, Question::FROM_USER);
                break;
        }
        $qid = $model->create_question($q);
        header('Content-Type: text/plain');
        echo '/question_bank/questions/' . $qid;
        http_response_code(201);
        die;
    } catch (ConflictException $e) {
        Util::output_errors_and_die($e->getMessage(), 409);
    } catch (DatabaseException $e) {
        Util::output_errors_and_die($e->getMessage(), 503);
    } catch (Exception $e) {
        Util::output_errors_and_die($e->getMessage(), 400);
    }
}