= Overview

nREPL largely consists of three abstractions: xref:design/handlers.adoc[handlers], xref:design/middleware.adoc[middleware], and xref:design/transports.adoc[transports].
These are roughly analogous to the handlers, middleware, and
adapters of https://github.com/ring-clojure/ring[Ring], though there are some
important semantic differences. Finally, nREPL is fundamentally message-oriented
and asynchronous (in contrast to most REPLs that build on top of streams
provided by e.g.  terminals).

== Messages

It is convention to express nREPL messages as EDN (Clojure) maps. For most purposes, it's
sufficient to imagine that we communicate with nREPL via EDN, much the same way
as we send and receive JSON to and from a REST endpoint. This is typically not
what actually happens, and the details are discussed in
xref:design/transports.adoc[the transport section], however, this conceptual
simplification serves us well.

=== Requests

Each message sent to an nREPL endpoint constitutes a "request" to perform a
particular operation, which is indicated by a `:op` entry.  Each operation may
further require the incoming message to contain other data.  Which data an
operation requires or may accept varies; for example, a message to evaluate
some code might look like this:

[source,clojure]
----
{:op "eval" :code "(+ 1 2 3)"}
----

The result(s) of performing each operation may be sent back to the nREPL client
in one or more response messages, the contents of which again depend upon the
operation.

=== Responses

The server may produce multiple messages in response to each client message (request).
The structure of the response is unique per each message type, but there are a few
fundamental properties that will always be around in the responses:

- `:id` The ID of the request for which the response was generated.
- `:session` The ID of the session for which the response was generated.
- `:status` The status of the response. Here there would either be something like "done"
if a request has been fully processed or the reason for a failure (e.g. "namespace-not-found"). Not every
response message would have the status key. If some request generated multiple response messages only the
final one would have the status attached to it.

As mentioned earlier each op would produce different response messages. Here's what you can expect
to see in responses generated as a result of an `eval` op invocation.

- `:ns` The stringified value of `\*ns*` at the time of the response message's
  generation.
- `:out` Contains content written to `\*out*` while the request's code was being evaluated.  Messages containing `*out*` content may be sent at the discretion
of the server, though at minimum corresponding with flushes of the underlying
stream/writer.
- `:err` Same as `:out`, but for `\*err*`.
- `:value` The result of printing a result of evaluating a form in the code sent
  in the corresponding request.  More than one value may be sent, if more than
one form can be read from the request's code string.  In contrast to the output
written to `\*out*` and `\*err*`, this may be usefully/reliably read and utilized
by the client, e.g. in tooling contexts, assuming the evaluated code returns a
printable and readable value.  Interactive clients will likely want to simply
stream ``:value``'s content to their UI's primary output / log.

Note that evaluations that are interrupted may nevertheless result
in multiple response messages being sent prior to the interrupt
occurring.

[TIP]
====
Your favourite editor/nREPL client might have some utility to
monitor the exchange of messages between the client and nREPL
(e.g. CIDER has a `*nrepl-messages*` where you can monitor all
requests and responses). That's a great way to get a better understanding
of nREPL server responses.
====

A partial `clojure.spec` for nREPL messages in provided as `nrepl.spec`. This covers
most messages/responses supported by the default middlewares.
