[[introduction]]
== Introduction

[.lead]
[yada]#yada# is a web library for ((Clojure)) that lets you write websites and web APIs that conform to HTTP standards.

Despite some differences, virtually all web libraries do a similar thing: call your code with some request data and ask you to return a response, leaving the bulk of the responsibililty for implementing the ((HTTP)) standards in your hands: responding with the correct status codes, response headers and ensuring semantics have been followed properly.

[yada]#yada# is *different*. Rather than leaving all the implementation details to you, it helps you out in _doing the right thing_ (according to HTTP standards), thereby creating a _better web_ footnote:[https://www.pandastrike.com/posts/20151019-create-more-web].

It achieves this by providing you with a highly-configurable handler that is general enough to use in the vast majority of cases. Rather than _coding_ the handler, the developer only has to _configure_ one. This declarative approach provides greater scope for *accuracy*, *consistency* and *re-use*.

[yada]#yada# represents a break from the traditional yet stale method of building web backends, an approach that can trace its roots all the way back to the days of https://en.wikipedia.org/wiki/Common_Gateway_Interface[Common Gateway Interface]. While [yada]#yada#'s data-oriented approach takes full advantage of the data-oriented philosophy of Clojure, there's no reason why this methodology cannot be implemented by new web libraries in other languages.

Using [yada]#yada# for your web project will allow you to finally exploit and benefit from the many features embodied in the outstanding design of HTTP, for *scale*, *flexibility*, *security*, *longevity* and *interoperability*.

=== Design goals

[yada]#yada# is designed to meet the following goals:

- Be easy to use for intermediate Clojure developers
- Comprehensive compliance with HTTP standards over pragmatism and performance
- Increase productivity through re-use
- Handle large workloads with reasonable performance
- Support multiple architectural styles, including Hypermedia APIs (REST)

[yada]#yada# is not an experiment. It is designed for, and has been tested in, production environments.

[yada]#yada# is sufficiently quick-and-easy for quick prototype work but scales up when you need it to, to feature-rich secure services that can handle the most demanding workloads, while remaining faithful to the HTTP standards.

Some familiarity with HTTP will help you understand [yada]#yada# concepts quicker, but isn't absolutely necessary. As you learn how to wield [yada]#yada# you will also discover and learn more about the HTTP standards as you go.

=== Say 'Hello!' to [yada-large]#yada#

It's quick to get started with [yada]#yada# without knowing how it works - it's easy to get started even if you only have a basic knowledge of Clojure.

Let's begin with a few examples. The obligatory *((Hello World!))* example is link:intro-examples/hello[`(yada/handler "Hello World!")`], which responds with a message.

Perhaps you might want to serve a file? That's
link:intro-examples/index.html[`(yada/handler (new java.io.File "index.html"))`].

Now you know how to serve a file, you know how to link:intro-examples/dir/[serve a directory]. But perhaps you've got some resources on the classpath?
`(yada/handler (clojure.java.io/resource
"talks/"))`.

What about link:intro-examples/nil[`(yada/handler nil)`]? Without knowing, can you guess what that might do? (That's right, it produces a `404 Not Found` response).

What about a quick dice generator? link:intro-examples/dice[`(yada/handler #(inc (rand-int 6)))`].
Notice we use a function here, rather than a constant value, to vary numbers between rolls.

How about streaming those dice rolls as 'Server Sent Events'? Put those
link:intro-examples/sse-dice[dice rolls on a core.async channel], and return it with [yada]#yada#.

All these examples demonstrate the use of Clojure types that are
converted on-the-fly into [yada]#yada# resources, and you can create your own
types too.

Let's delve a little deeper…

=== Resources

In [yada]#yada#, resources are defined by a plain-old Clojure map.

This has many benefits. While functions are opaque, data is open to
inspection. Data structures are easy to generate, transform and query -
chores that Clojure makes light work of.

Here's an example of a resource:

[source,clojure]
----
(yada/resource
  {:properties {…}
   :methods {:get {:response (fn [ctx] "Hello World!")}
             :put {…}
             :brew {…}}
 …
})
----

There's a lot of things you can do with a resource data model but perhaps the most obvious is to create a request handler from it to create responses from HTTP requests. That's the role of a **handler**.

With [yada]#yada#, we transform a resource into a handler using the `handler` function.

[source,clojure]
----
(require '[yada.yada :as yada])

(yada/handler (yada/resource {…}))
----

A handler can be called as a function, with a single argument representing an HTTP **request**. It returns a value representing the corresponding HTTP response.

NOTE: A [yada]#yada# handler is an instance of the `yada.handler/Handler` record. Since this record satisfies `clojure.lang.IFn`, [yada]#yada# handlers behave just like normal Ring handlers and can be used wherever you might use a Ring handler.

=== Serving requests

To use [yada]#yada# to create real responses to real HTTP requests, you need to add [yada]#yada# to a web-server. The web server takes care of the networking and messages of HTTP (RFC 7230), while [yada]#yada# focuses on the semantics and content (<<RFC7231>> and upwards).

[NOTE]
--
Currently, the only web server you can use is link:https://github.com/ztellman/aleph[icon:github[github,width="12pt"]ztellman/aleph]. This is because [yada]#yada# is built on an asynchronous abstraction provided by link:https://github.com/ztellman/manifold[icon:github[github,width="12pt"]ztellman/manifold]. However, there is no technical reason why, in future, other web servers can't be wrapped by manifold.

In the meantime, Aleph (which wraps a much bigger library, Netty) provides a very capable and performant server.
--

To write real applications you also need a router that understands URIs, and [yada]#yada# has some features that are enabled when used with https://github.com/juxt/bidi[icon:github[github,width="12pt"]juxt/bidi], although there is nothing to stop you using [yada]#yada# with other routing libraries.

=== Conclusion

That's [yada]#yada# in a nutshell, but the quickest way to to learn it is to set up an environment and play. That's what we'll do in the <<getting-started,next chapter>>.
