Creating Routes to deal with a form So I have created a block in which I've added a form, build with the form API. It contains a textfield and a submit button. My next step is to create a route that calls a method in a controller in my Module.

I am wondering how to do this. The form itself part of the main menu, so visible on any page. I'm not sure how to define this route. I've read there are form routes, but I don't think that's what I am looking for. 

The Drupal Form API documentation says something like this:

module_search.form:
  path: '/'
  defaults:
    _title: 'Search form'
    _form: 'Drupal\module_search\Form\SearchForm'
  requirements:
    _permission: 'access content'


But I have no clue how to handle the request itself to do something with the data this form provides.
If you want a form in the main menu of every page, you don't need a route for it.  You can just create a block, either for just the search form or for the main menu, and load the form in as a variable into that block.

namespace Drupal\module_search\Plugin\Block;

use Drupal\Core\Block\BlockBase;

/**
 * Provides a 'Header Search Block Form' block.
 *
 * @Block(
 *  id = "header_search_block",
 *  admin_label = @Translation("Header Search Form Block"),
 * )
 */
class HeaderSearchFormBlock extends BlockBase {

  /**
   * {@inheritdoc}
   */
  public function build() {

    $form = \Drupal::formBuilder()-&gt;getForm('Drupal\module_search\Form\SearchForm');
    return [
      $form,
      '#cache' =&gt; [
        'contexts' =&gt; ['url.path', 'url.query_args']
      ],
    ];
  }
}


What you're returning is a render array, so you might want caching settings on there, otherwise, you can just return the form itself.  If you want to prefill the search term on every page, you'd want a cache context that includes page arguments, like above.  If you want the fields empty, such as if your form only contains a textfield for searching, then you don't need a separate cached version on every page and you can just return the form in your build() function:

  public function build() {   
    return \Drupal::formBuilder()-&gt;getForm('Drupal\module_search\Form\SearchForm');    
  }


Another option, you can preprocess your main menu block to add the form as a variable as well.

function mymodule_preprocess_block__system_menu_block__header_menu(&amp;$variables) {
  $variables['search_form'] = \Drupal::formBuilder()-&gt;getForm('Drupal\module_search\Form\SearchForm');
}


then in your block template (such as block--system-menu-block--header-menu.html.twig)

add

{{ search_form }}


As far as redirecting to search, my preferred method is with javascript, as you don't need to hit the backend.  You can just redirect to your search page from the javascript.

Just attach the javascript library to your form

$form['#attached']['library'][] = 'mymodule/mymodule.header_search';


(etc.  there are many tutorials on this)

and then in the javascript do something like:

 $('#' + formID).submit(function(e) {
   e.preventDefault();
   var filters = self.gatherFilters();
   var url = searchURL + '?' + $.param(filters);
   window.location.href = url;
 });


If for some reason, you need backend processing, your form can have a submitForm method that then sets the redirect on the $form_state object:

$query = ['keyword' =&gt; $search_term];    
$form_state-&gt;setRedirect($route_name, [], ['query' =&gt; $query]);


with $query being an array of query arguments.

For your search results page, I would recommend you create a different search form.  As a small textfield in the header is different than filters on a form.

Without custom coding, you could use a Drupal view page, and set a contextual filter set to keyword, or you could create a controller in your custom module that returns a different search form with filters as well as the results from Elastisearch.