Moved tutorial to servant-examples/tutorial and include it in doc/index.rst
This commit is contained in:
parent
7bb393fe17
commit
1d4e3a1e5b
19 changed files with 13 additions and 545 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -25,4 +25,4 @@ Setup
|
||||||
.stack-work
|
.stack-work
|
||||||
shell.nix
|
shell.nix
|
||||||
default.nix
|
default.nix
|
||||||
tutorial/_build
|
doc/_build
|
||||||
|
|
13
doc/conf.py
13
doc/conf.py
|
@ -37,7 +37,7 @@ templates_path = ['_templates']
|
||||||
|
|
||||||
# The suffix(es) of source filenames.
|
# The suffix(es) of source filenames.
|
||||||
# You can specify multiple suffix as a list of string:
|
# You can specify multiple suffix as a list of string:
|
||||||
source_suffix = ['.md', '.rst']
|
source_suffix = ['.md', '.rst', '.lhs']
|
||||||
|
|
||||||
# The encoding of source files.
|
# The encoding of source files.
|
||||||
#source_encoding = 'utf-8-sig'
|
#source_encoding = 'utf-8-sig'
|
||||||
|
@ -47,8 +47,8 @@ master_doc = 'index'
|
||||||
|
|
||||||
# General information about the project.
|
# General information about the project.
|
||||||
project = u'servant'
|
project = u'servant'
|
||||||
copyright = u'2015-2016, Servant contributors'
|
copyright = u'2016, Servant Contributors'
|
||||||
author = u'Servant contributors'
|
author = u'Servant Contributors'
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
# The version info for the project you're documenting, acts as replacement for
|
||||||
# |version| and |release|, also used in various other places throughout the
|
# |version| and |release|, also used in various other places throughout the
|
||||||
|
@ -74,7 +74,7 @@ language = None
|
||||||
|
|
||||||
# List of patterns, relative to source directory, that match files and
|
# List of patterns, relative to source directory, that match files and
|
||||||
# directories to ignore when looking for source files.
|
# directories to ignore when looking for source files.
|
||||||
exclude_patterns = ['_build']
|
exclude_patterns = ['_build', 'venv']
|
||||||
|
|
||||||
# The reST default role (used for this markup: `text`) to use for all
|
# The reST default role (used for this markup: `text`) to use for all
|
||||||
# documents.
|
# documents.
|
||||||
|
@ -108,7 +108,7 @@ todo_include_todos = False
|
||||||
|
|
||||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
# The theme to use for HTML and HTML Help pages. See the documentation for
|
||||||
# a list of builtin themes.
|
# a list of builtin themes.
|
||||||
# html_theme = 'alabaster'
|
html_theme = 'sphinx_rtd_theme'
|
||||||
|
|
||||||
# Theme options are theme-specific and customize the look and feel of a theme
|
# Theme options are theme-specific and customize the look and feel of a theme
|
||||||
# further. For a list of options available for each theme, see the
|
# further. For a list of options available for each theme, see the
|
||||||
|
@ -223,7 +223,7 @@ latex_elements = {
|
||||||
# author, documentclass [howto, manual, or own class]).
|
# author, documentclass [howto, manual, or own class]).
|
||||||
latex_documents = [
|
latex_documents = [
|
||||||
(master_doc, 'servant.tex', u'servant Documentation',
|
(master_doc, 'servant.tex', u'servant Documentation',
|
||||||
u'Servant contributors', 'manual'),
|
u'Servant Contributors', 'manual'),
|
||||||
]
|
]
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top of
|
# The name of an image file (relative to this directory) to place at the top of
|
||||||
|
@ -285,4 +285,5 @@ texinfo_documents = [
|
||||||
|
|
||||||
source_parsers = {
|
source_parsers = {
|
||||||
'.md': CommonMarkParser,
|
'.md': CommonMarkParser,
|
||||||
|
'.lhs': CommonMarkParser,
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,8 @@ Documentation table of contents
|
||||||
-------------------------------
|
-------------------------------
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
README.md
|
README.md
|
||||||
|
tutorial/index.rst
|
||||||
CONTRIBUTING.md
|
CONTRIBUTING.md
|
||||||
|
|
||||||
|
|
1
doc/tutorial
Symbolic link
1
doc/tutorial
Symbolic link
|
@ -0,0 +1 @@
|
||||||
|
../servant-examples/tutorial
|
|
@ -1,49 +0,0 @@
|
||||||
{-# LANGUAGE DataKinds #-}
|
|
||||||
{-# LANGUAGE TypeFamilies #-}
|
|
||||||
{-# LANGUAGE TypeOperators #-}
|
|
||||||
module T8 where
|
|
||||||
|
|
||||||
import Control.Monad.Trans.Except
|
|
||||||
import Network.HTTP.Client (Manager, defaultManagerSettings,
|
|
||||||
newManager)
|
|
||||||
import Servant
|
|
||||||
import Servant.Client
|
|
||||||
import System.IO.Unsafe (unsafePerformIO)
|
|
||||||
|
|
||||||
import T3
|
|
||||||
|
|
||||||
position :: Int -- ^ value for "x"
|
|
||||||
-> Int -- ^ value for "y"
|
|
||||||
-> ExceptT ServantError IO Position
|
|
||||||
|
|
||||||
hello :: Maybe String -- ^ an optional value for "name"
|
|
||||||
-> ExceptT ServantError IO HelloMessage
|
|
||||||
|
|
||||||
marketing :: ClientInfo -- ^ value for the request body
|
|
||||||
-> ExceptT ServantError IO Email
|
|
||||||
|
|
||||||
position :<|> hello :<|> marketing = client api baseUrl manager
|
|
||||||
|
|
||||||
baseUrl :: BaseUrl
|
|
||||||
baseUrl = BaseUrl Http "localhost" 8081 ""
|
|
||||||
|
|
||||||
{-# NOINLINE manager #-}
|
|
||||||
manager :: Manager
|
|
||||||
manager = unsafePerformIO $ newManager defaultManagerSettings
|
|
||||||
|
|
||||||
queries :: ExceptT ServantError IO (Position, HelloMessage, Email)
|
|
||||||
queries = do
|
|
||||||
pos <- position 10 10
|
|
||||||
msg <- hello (Just "servant")
|
|
||||||
em <- marketing (ClientInfo "Alp" "alp@foo.com" 26 ["haskell", "mathematics"])
|
|
||||||
return (pos, msg, em)
|
|
||||||
|
|
||||||
run :: IO ()
|
|
||||||
run = do
|
|
||||||
res <- runExceptT queries
|
|
||||||
case res of
|
|
||||||
Left err -> putStrLn $ "Error: " ++ show err
|
|
||||||
Right (pos, msg, em) -> do
|
|
||||||
print pos
|
|
||||||
print msg
|
|
||||||
print em
|
|
|
@ -59,7 +59,7 @@ Tutorial
|
||||||
---------
|
---------
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 1
|
||||||
|
|
||||||
api-type.lhs
|
api-type.lhs
|
||||||
server.lhs
|
server.lhs
|
|
@ -1,4 +0,0 @@
|
||||||
import T8
|
|
||||||
|
|
||||||
main :: IO ()
|
|
||||||
main = run
|
|
|
@ -1,26 +0,0 @@
|
||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
|
||||||
<title>Tutorial - 9 - servant-jquery</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<h1>Books</h1>
|
|
||||||
<input type="search" name="q" id="q" placeholder="Search author or book title..." />
|
|
||||||
<div>
|
|
||||||
<p>Results for <strong id="query">""</strong></p>
|
|
||||||
<ul id="results">
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<hr />
|
|
||||||
<h1>Approximating π</h1>
|
|
||||||
<p>Count: <span id="count">0</span></p>
|
|
||||||
<p>Successes: <span id="successes">0</span></p>
|
|
||||||
<p id="pi"></p>
|
|
||||||
|
|
||||||
<script type="text/javascript" src="/jq.js"></script>
|
|
||||||
<script type="text/javascript" src="/api.js"></script>
|
|
||||||
<script type="text/javascript" src="/ui.js"></script>
|
|
||||||
|
|
||||||
</body>
|
|
|
@ -1,61 +0,0 @@
|
||||||
/* book search */
|
|
||||||
function updateResults(data)
|
|
||||||
{
|
|
||||||
console.log(data);
|
|
||||||
$('#results').html("");
|
|
||||||
$('#query').text("\"" + data.query + "\"");
|
|
||||||
for(var i = 0; i < data.results.length; i++)
|
|
||||||
{
|
|
||||||
$('#results').append(renderBook(data.results[i]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function renderBook(book)
|
|
||||||
{
|
|
||||||
var li = '<li><strong>' + book.title + '</strong>, <i>'
|
|
||||||
+ book.author + '</i> - ' + book.year + '</li>';
|
|
||||||
return li;
|
|
||||||
}
|
|
||||||
|
|
||||||
function searchBooks()
|
|
||||||
{
|
|
||||||
var q = $('#q').val();
|
|
||||||
getBooks(q, updateResults, console.log)
|
|
||||||
}
|
|
||||||
|
|
||||||
searchBooks();
|
|
||||||
$('#q').keyup(function() {
|
|
||||||
searchBooks();
|
|
||||||
});
|
|
||||||
|
|
||||||
/* approximating pi */
|
|
||||||
var count = 0;
|
|
||||||
var successes = 0;
|
|
||||||
|
|
||||||
function f(data)
|
|
||||||
{
|
|
||||||
var x = data.x, y = data.y;
|
|
||||||
if(x*x + y*y <= 1)
|
|
||||||
{
|
|
||||||
successes++;
|
|
||||||
}
|
|
||||||
|
|
||||||
count++;
|
|
||||||
|
|
||||||
update('#count', count);
|
|
||||||
update('#successes', successes);
|
|
||||||
update('#pi', 4*successes/count);
|
|
||||||
}
|
|
||||||
|
|
||||||
function update(id, val)
|
|
||||||
{
|
|
||||||
$(id).text(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
function refresh()
|
|
||||||
{
|
|
||||||
getPoint(f, console.log);
|
|
||||||
}
|
|
||||||
|
|
||||||
window.setInterval(refresh, 200);
|
|
||||||
|
|
|
@ -1,39 +0,0 @@
|
||||||
import Network.Wai
|
|
||||||
import Network.Wai.Handler.Warp
|
|
||||||
import System.Environment
|
|
||||||
|
|
||||||
import qualified T1
|
|
||||||
import qualified T10
|
|
||||||
import qualified T2
|
|
||||||
import qualified T3
|
|
||||||
import qualified T4
|
|
||||||
import qualified T5
|
|
||||||
import qualified T6
|
|
||||||
import qualified T7
|
|
||||||
import qualified T9
|
|
||||||
|
|
||||||
app :: String -> (Application -> IO ()) -> IO ()
|
|
||||||
app n f = case n of
|
|
||||||
"1" -> f T1.app
|
|
||||||
"2" -> f T2.app
|
|
||||||
"3" -> f T3.app
|
|
||||||
"4" -> f T4.app
|
|
||||||
"5" -> f T5.app
|
|
||||||
"6" -> f T6.app
|
|
||||||
"7" -> f T7.app
|
|
||||||
"8" -> f T3.app
|
|
||||||
"9" -> T9.writeJSFiles >> f T9.app
|
|
||||||
"10" -> f T10.app
|
|
||||||
_ -> usage
|
|
||||||
|
|
||||||
main :: IO ()
|
|
||||||
main = do
|
|
||||||
args <- getArgs
|
|
||||||
case args of
|
|
||||||
[n] -> app n (run 8081)
|
|
||||||
_ -> usage
|
|
||||||
|
|
||||||
usage :: IO ()
|
|
||||||
usage = do
|
|
||||||
putStrLn "Usage:\t tutorial N"
|
|
||||||
putStrLn "\t\twhere N is the number of the example you want to run."
|
|
288
tutorial/conf.py
288
tutorial/conf.py
|
@ -1,288 +0,0 @@
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
#
|
|
||||||
# servant documentation build configuration file, created by
|
|
||||||
# sphinx-quickstart on Fri Jan 22 12:22:48 2016.
|
|
||||||
#
|
|
||||||
# This file is execfile()d with the current directory set to its
|
|
||||||
# containing dir.
|
|
||||||
#
|
|
||||||
# Note that not all possible configuration values are present in this
|
|
||||||
# autogenerated file.
|
|
||||||
#
|
|
||||||
# All configuration values have a default; values that are commented out
|
|
||||||
# serve to show the default.
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
from recommonmark.parser import CommonMarkParser
|
|
||||||
|
|
||||||
# If extensions (or modules to document with autodoc) are in another directory,
|
|
||||||
# add these directories to sys.path here. If the directory is relative to the
|
|
||||||
# documentation root, use os.path.abspath to make it absolute, like shown here.
|
|
||||||
#sys.path.insert(0, os.path.abspath('.'))
|
|
||||||
|
|
||||||
# -- General configuration ------------------------------------------------
|
|
||||||
|
|
||||||
# If your documentation needs a minimal Sphinx version, state it here.
|
|
||||||
#needs_sphinx = '1.0'
|
|
||||||
|
|
||||||
# Add any Sphinx extension module names here, as strings. They can be
|
|
||||||
# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom
|
|
||||||
# ones.
|
|
||||||
extensions = []
|
|
||||||
|
|
||||||
# Add any paths that contain templates here, relative to this directory.
|
|
||||||
templates_path = ['_templates']
|
|
||||||
|
|
||||||
# The suffix(es) of source filenames.
|
|
||||||
# You can specify multiple suffix as a list of string:
|
|
||||||
source_suffix = ['.md', '.rst', '.lhs']
|
|
||||||
|
|
||||||
# The encoding of source files.
|
|
||||||
#source_encoding = 'utf-8-sig'
|
|
||||||
|
|
||||||
# The master toctree document.
|
|
||||||
master_doc = 'index'
|
|
||||||
|
|
||||||
# General information about the project.
|
|
||||||
project = u'servant'
|
|
||||||
copyright = u'2016, Servant Contributors'
|
|
||||||
author = u'Servant Contributors'
|
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
|
||||||
# |version| and |release|, also used in various other places throughout the
|
|
||||||
# built documents.
|
|
||||||
#
|
|
||||||
# The short X.Y version.
|
|
||||||
version = u'0.1'
|
|
||||||
# The full version, including alpha/beta/rc tags.
|
|
||||||
release = u'0.1'
|
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
|
||||||
# for a list of supported languages.
|
|
||||||
#
|
|
||||||
# This is also used if you do content translation via gettext catalogs.
|
|
||||||
# Usually you set "language" from the command line for these cases.
|
|
||||||
language = None
|
|
||||||
|
|
||||||
# There are two options for replacing |today|: either, you set today to some
|
|
||||||
# non-false value, then it is used:
|
|
||||||
#today = ''
|
|
||||||
# Else, today_fmt is used as the format for a strftime call.
|
|
||||||
#today_fmt = '%B %d, %Y'
|
|
||||||
|
|
||||||
# List of patterns, relative to source directory, that match files and
|
|
||||||
# directories to ignore when looking for source files.
|
|
||||||
exclude_patterns = ['_build', 'venv']
|
|
||||||
|
|
||||||
# The reST default role (used for this markup: `text`) to use for all
|
|
||||||
# documents.
|
|
||||||
#default_role = None
|
|
||||||
|
|
||||||
# If true, '()' will be appended to :func: etc. cross-reference text.
|
|
||||||
#add_function_parentheses = True
|
|
||||||
|
|
||||||
# If true, the current module name will be prepended to all description
|
|
||||||
# unit titles (such as .. function::).
|
|
||||||
#add_module_names = True
|
|
||||||
|
|
||||||
# If true, sectionauthor and moduleauthor directives will be shown in the
|
|
||||||
# output. They are ignored by default.
|
|
||||||
#show_authors = False
|
|
||||||
|
|
||||||
# The name of the Pygments (syntax highlighting) style to use.
|
|
||||||
pygments_style = 'sphinx'
|
|
||||||
|
|
||||||
# A list of ignored prefixes for module index sorting.
|
|
||||||
#modindex_common_prefix = []
|
|
||||||
|
|
||||||
# If true, keep warnings as "system message" paragraphs in the built documents.
|
|
||||||
#keep_warnings = False
|
|
||||||
|
|
||||||
# If true, `todo` and `todoList` produce output, else they produce nothing.
|
|
||||||
todo_include_todos = False
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for HTML output ----------------------------------------------
|
|
||||||
|
|
||||||
# The theme to use for HTML and HTML Help pages. See the documentation for
|
|
||||||
# a list of builtin themes.
|
|
||||||
html_theme = 'sphinx_rtd_theme'
|
|
||||||
|
|
||||||
# Theme options are theme-specific and customize the look and feel of a theme
|
|
||||||
# further. For a list of options available for each theme, see the
|
|
||||||
# documentation.
|
|
||||||
#html_theme_options = {}
|
|
||||||
|
|
||||||
# Add any paths that contain custom themes here, relative to this directory.
|
|
||||||
#html_theme_path = []
|
|
||||||
|
|
||||||
# The name for this set of Sphinx documents. If None, it defaults to
|
|
||||||
# "<project> v<release> documentation".
|
|
||||||
#html_title = None
|
|
||||||
|
|
||||||
# A shorter title for the navigation bar. Default is the same as html_title.
|
|
||||||
#html_short_title = None
|
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top
|
|
||||||
# of the sidebar.
|
|
||||||
#html_logo = None
|
|
||||||
|
|
||||||
# The name of an image file (within the static path) to use as favicon of the
|
|
||||||
# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32
|
|
||||||
# pixels large.
|
|
||||||
#html_favicon = None
|
|
||||||
|
|
||||||
# Add any paths that contain custom static files (such as style sheets) here,
|
|
||||||
# relative to this directory. They are copied after the builtin static files,
|
|
||||||
# so a file named "default.css" will overwrite the builtin "default.css".
|
|
||||||
html_static_path = ['_static']
|
|
||||||
|
|
||||||
# Add any extra paths that contain custom files (such as robots.txt or
|
|
||||||
# .htaccess) here, relative to this directory. These files are copied
|
|
||||||
# directly to the root of the documentation.
|
|
||||||
#html_extra_path = []
|
|
||||||
|
|
||||||
# If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
|
|
||||||
# using the given strftime format.
|
|
||||||
#html_last_updated_fmt = '%b %d, %Y'
|
|
||||||
|
|
||||||
# If true, SmartyPants will be used to convert quotes and dashes to
|
|
||||||
# typographically correct entities.
|
|
||||||
#html_use_smartypants = True
|
|
||||||
|
|
||||||
# Custom sidebar templates, maps document names to template names.
|
|
||||||
#html_sidebars = {}
|
|
||||||
|
|
||||||
# Additional templates that should be rendered to pages, maps page names to
|
|
||||||
# template names.
|
|
||||||
#html_additional_pages = {}
|
|
||||||
|
|
||||||
# If false, no module index is generated.
|
|
||||||
#html_domain_indices = True
|
|
||||||
|
|
||||||
# If false, no index is generated.
|
|
||||||
#html_use_index = True
|
|
||||||
|
|
||||||
# If true, the index is split into individual pages for each letter.
|
|
||||||
#html_split_index = False
|
|
||||||
|
|
||||||
# If true, links to the reST sources are added to the pages.
|
|
||||||
#html_show_sourcelink = True
|
|
||||||
|
|
||||||
# If true, "Created using Sphinx" is shown in the HTML footer. Default is True.
|
|
||||||
#html_show_sphinx = True
|
|
||||||
|
|
||||||
# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True.
|
|
||||||
#html_show_copyright = True
|
|
||||||
|
|
||||||
# If true, an OpenSearch description file will be output, and all pages will
|
|
||||||
# contain a <link> tag referring to it. The value of this option must be the
|
|
||||||
# base URL from which the finished HTML is served.
|
|
||||||
#html_use_opensearch = ''
|
|
||||||
|
|
||||||
# This is the file name suffix for HTML files (e.g. ".xhtml").
|
|
||||||
#html_file_suffix = None
|
|
||||||
|
|
||||||
# Language to be used for generating the HTML full-text search index.
|
|
||||||
# Sphinx supports the following languages:
|
|
||||||
# 'da', 'de', 'en', 'es', 'fi', 'fr', 'hu', 'it', 'ja'
|
|
||||||
# 'nl', 'no', 'pt', 'ro', 'ru', 'sv', 'tr'
|
|
||||||
#html_search_language = 'en'
|
|
||||||
|
|
||||||
# A dictionary with options for the search language support, empty by default.
|
|
||||||
# Now only 'ja' uses this config value
|
|
||||||
#html_search_options = {'type': 'default'}
|
|
||||||
|
|
||||||
# The name of a javascript file (relative to the configuration directory) that
|
|
||||||
# implements a search results scorer. If empty, the default will be used.
|
|
||||||
#html_search_scorer = 'scorer.js'
|
|
||||||
|
|
||||||
# Output file base name for HTML help builder.
|
|
||||||
htmlhelp_basename = 'servantdoc'
|
|
||||||
|
|
||||||
# -- Options for LaTeX output ---------------------------------------------
|
|
||||||
|
|
||||||
latex_elements = {
|
|
||||||
# The paper size ('letterpaper' or 'a4paper').
|
|
||||||
#'papersize': 'letterpaper',
|
|
||||||
|
|
||||||
# The font size ('10pt', '11pt' or '12pt').
|
|
||||||
#'pointsize': '10pt',
|
|
||||||
|
|
||||||
# Additional stuff for the LaTeX preamble.
|
|
||||||
#'preamble': '',
|
|
||||||
|
|
||||||
# Latex figure (float) alignment
|
|
||||||
#'figure_align': 'htbp',
|
|
||||||
}
|
|
||||||
|
|
||||||
# Grouping the document tree into LaTeX files. List of tuples
|
|
||||||
# (source start file, target name, title,
|
|
||||||
# author, documentclass [howto, manual, or own class]).
|
|
||||||
latex_documents = [
|
|
||||||
(master_doc, 'servant.tex', u'servant Documentation',
|
|
||||||
u'Servant Contributors', 'manual'),
|
|
||||||
]
|
|
||||||
|
|
||||||
# The name of an image file (relative to this directory) to place at the top of
|
|
||||||
# the title page.
|
|
||||||
#latex_logo = None
|
|
||||||
|
|
||||||
# For "manual" documents, if this is true, then toplevel headings are parts,
|
|
||||||
# not chapters.
|
|
||||||
#latex_use_parts = False
|
|
||||||
|
|
||||||
# If true, show page references after internal links.
|
|
||||||
#latex_show_pagerefs = False
|
|
||||||
|
|
||||||
# If true, show URL addresses after external links.
|
|
||||||
#latex_show_urls = False
|
|
||||||
|
|
||||||
# Documents to append as an appendix to all manuals.
|
|
||||||
#latex_appendices = []
|
|
||||||
|
|
||||||
# If false, no module index is generated.
|
|
||||||
#latex_domain_indices = True
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for manual page output ---------------------------------------
|
|
||||||
|
|
||||||
# One entry per manual page. List of tuples
|
|
||||||
# (source start file, name, description, authors, manual section).
|
|
||||||
man_pages = [
|
|
||||||
(master_doc, 'servant', u'servant Documentation',
|
|
||||||
[author], 1)
|
|
||||||
]
|
|
||||||
|
|
||||||
# If true, show URL addresses after external links.
|
|
||||||
#man_show_urls = False
|
|
||||||
|
|
||||||
|
|
||||||
# -- Options for Texinfo output -------------------------------------------
|
|
||||||
|
|
||||||
# Grouping the document tree into Texinfo files. List of tuples
|
|
||||||
# (source start file, target name, title, author,
|
|
||||||
# dir menu entry, description, category)
|
|
||||||
texinfo_documents = [
|
|
||||||
(master_doc, 'servant', u'servant Documentation',
|
|
||||||
author, 'servant', 'One line description of project.',
|
|
||||||
'Miscellaneous'),
|
|
||||||
]
|
|
||||||
|
|
||||||
# Documents to append as an appendix to all manuals.
|
|
||||||
#texinfo_appendices = []
|
|
||||||
|
|
||||||
# If false, no module index is generated.
|
|
||||||
#texinfo_domain_indices = True
|
|
||||||
|
|
||||||
# How to display URL addresses: 'footnote', 'no', or 'inline'.
|
|
||||||
#texinfo_show_urls = 'footnote'
|
|
||||||
|
|
||||||
# If true, do not generate a @detailmenu in the "Top" node's menu.
|
|
||||||
#texinfo_no_detailmenu = False
|
|
||||||
|
|
||||||
source_parsers = {
|
|
||||||
'.md': CommonMarkParser,
|
|
||||||
'.lhs': CommonMarkParser,
|
|
||||||
}
|
|
|
@ -1,68 +0,0 @@
|
||||||
Servant tutorial
|
|
||||||
================
|
|
||||||
|
|
||||||
This is an introductory tutorial to the current version of *servant*, which is **0.4**. Any comment or issue can be directed to [this website's issue tracker](http://github.com/haskell-servant/haskell-servant.github.io/issues).
|
|
||||||
|
|
||||||
Github
|
|
||||||
-------
|
|
||||||
|
|
||||||
- the servant packages: [haskell-servant/servant](https://github.com/haskell-servant/servant)
|
|
||||||
- the website (including this tutorial): [haskell-servant/haskell-servant.github.io](https://github.com/haskell-servant/haskell-servant.github.io/)
|
|
||||||
- Feel free to use the issue tracker (or to send PRs!) on the website's repository to give feedback and suggestions about this tutorial
|
|
||||||
|
|
||||||
Introduction
|
|
||||||
-------------
|
|
||||||
|
|
||||||
*servant* has the following guiding principles:
|
|
||||||
|
|
||||||
- concision
|
|
||||||
|
|
||||||
This is a pretty wide-ranging principle. You should be able to get nice
|
|
||||||
documentation for your web servers, and client libraries, without repeating
|
|
||||||
yourself. You should not have to manually serialize and deserialize your
|
|
||||||
resources, but only declare how to do those things *once per type*. If a
|
|
||||||
bunch of your handlers take the same query parameters, you shouldn't have to
|
|
||||||
repeat that logic for each handler, but instead just "apply" it to all of
|
|
||||||
them at once. Your handlers shouldn't be where composition goes to die. And
|
|
||||||
so on.
|
|
||||||
|
|
||||||
- flexibility
|
|
||||||
|
|
||||||
If we haven't thought of your use case, it should still be easily
|
|
||||||
achievable. If you want to use templating library X, go ahead. Forms? Do
|
|
||||||
them however you want, but without difficulty. We're not opinionated.
|
|
||||||
|
|
||||||
- separation of concerns
|
|
||||||
|
|
||||||
Your handlers and your HTTP logic should be separate. True to the philosphy
|
|
||||||
at the core of HTTP and REST, with *servant* your handlers return normal
|
|
||||||
Haskell datatypes - that's the resource. And then from a description of your
|
|
||||||
API, *servant* handles the *presentation* (i.e., the Content-Types). But
|
|
||||||
that's just one example.
|
|
||||||
|
|
||||||
- type safety
|
|
||||||
|
|
||||||
Want to be sure your API meets a specification? Your compiler can check
|
|
||||||
that for you. Links you can be sure exist? You got it.
|
|
||||||
|
|
||||||
To stick true to these principles, we do things a little differently than you
|
|
||||||
might expect. The core idea is *reifying the description of your API*. Once
|
|
||||||
reified, everything follows. We think we might be the first web framework to
|
|
||||||
reify API descriptions in an extensible way. We're pretty sure we're the first
|
|
||||||
to reify it as *types*.
|
|
||||||
|
|
||||||
To be able to write a webservice you only need to read the first two sections,
|
|
||||||
but the goal of this document being to get you started with servant, we also
|
|
||||||
cover the couple of ways you can extend servant for a great good.
|
|
||||||
|
|
||||||
Tutorial
|
|
||||||
---------
|
|
||||||
|
|
||||||
.. toctree::
|
|
||||||
:maxdepth: 2
|
|
||||||
|
|
||||||
api-type.lhs
|
|
||||||
server.lhs
|
|
||||||
client.lhs
|
|
||||||
javascript.lhs
|
|
||||||
docs.lhs
|
|
Loading…
Reference in a new issue