Skip to content

Commit

Permalink
rest and intro done
Browse files Browse the repository at this point in the history
  • Loading branch information
glozow committed Aug 20, 2019
1 parent a77f607 commit 0284332
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 12 deletions.
6 changes: 3 additions & 3 deletions docs/interfaces/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,18 +8,18 @@

This document describes how to create a commmand-line interface for an SDK application. A separate document for creating a module CLI can be found [here](#../module-interfaces.md#cli).

- [Application CLI](#application-cli)
- [Application CLI Components](#application-cli-components)
- [Commands](#commands)
- [Flags](#flags)
- [Initialization and Configurations](#initialization-and-configurations)

## Application CLI
## Application CLI Components

One of the main entrypoints of an application is the command-line interface. This entrypoint is created as a `main.go` file which compiles to a binary, conventionally placed in the application's `app/cmd/cli` folder. The CLI for an application will typically be referred to as the name of the application suffixed with `-cli`, e.g. `appcli`.

### Cobra

There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`]() interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to.
There is no set way to create a CLI, but SDK modules all use the [Cobra Library](https://github.com/spf13/cobra) in order to implement the [`AppModuleBasic`](../building-modules) interface. Building a CLI with Cobra entails defining commands, arguments, and flags. [**Commands**](#commands) represent the action users wish to take, such as `tx` for creating a transaction and `query` for querying the application. Each command can also have nested subcommands, necessary for naming the specific transaction type. Users also supply **Arguments**, such as account numbers to send coins to, and [**Flags**](#flags) to modify various aspects of the commands, such as gas prices or which node to broadcast to.

### Main Function

Expand Down
44 changes: 43 additions & 1 deletion docs/interfaces/interfaces-intro.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,45 @@
# Interfaces

This document introduces interfaces for SDK applications. The two main interfaces are the Command-Line Interface and REST Interface.
## Prerequisites

* [Anatomy of an SDK Application](../basics/app-anatomy.md)
* [Lifecycle of a Transaction](../basics/tx-lifecycle.md)


## Synopsis

Every application must include some interface users can use to interact with the defined functionalities. This document introduces user interfaces for SDK applications.

- [Types of Application Interfaces](#types-of-application-interfaces)
- [Module vs Application Interfaces](#module-vs-application-interfaces)
+ [Module Developer Responsibilities](#module-developer-responsibilities)
+ [Application Developer Responsibilities](#application-developer-responsibilities)


## Types of Application Interfaces

SDK applications should have a Command-Line Interface (CLI) and REST Interface to support HTTP requests. The SDK is opinionated about how to create these two interfaces; all modules specify [Cobra commands](https://github.com/spf13/cobra) and register routes using [Gorilla Mux routers](https://github.com/gorilla/mux).


## Module vs Application Interfaces

The CLI and REST Interface are conventionally defined in the application `/cmd/cli` folder. The process of creating an application interface is vastly different from a module interface, though the components are closely intertwined. As expected, the module interface handles the bulk of the underlying logic, unpacking user requests into arguments and routes, and neatly marshaling everything into ABCI requests to be handled by Baseapp. On the other hand, the application interface handles the user configurations and customizations, instantiates the application-specific values and objects, and passes everything to module interface functions.

### Module Developer Responsibilities

In regards to interfaces, the module developers' responsibilities include:

* **CLI commands:** Specifically, [Transaction commands](../building-modules/interfaces.md#transaction-commands) and [Query commands](../building-modules/interfaces.md#query-commands). These are commands that users will invoke when interacting with the application. For example, if an application enables sending coins through the [`auth`](https://github.com/cosmos/cosmos-sdk/tree/67f6b021180c7ef0bcf25b6597a629aca27766b8/docs/spec/auth) module, users will create `auth send` transactions.
* **Request Handlers:** Also categorized into Transaction and Query requests. Transactions will require HTTP [Request Types](../building-modules/interfaces.md#request-types) in addition to [Request Handlers](../building-modules/interfaces.md#request-handlers) in order to encapsulate all of the user's options (e.g. gas prices).
* **REST Routes:** Given a router, the module interface registers paths with the aforementioned [Request Handlers](../building-modules/interfaces.md#request-handlers) for each type of request.

Module interfaces are designed to be generic. Both commands and request types will include required user input (through flags or request body) which will be different for each application. This section of documents will only detail application interfaces; to read about how to build module interfaces, click [here](../building-modules/interfaces.md).

### Application Developer Responsibilities

In regards to interfaces, the application developers' responsibilities include:

* **CLI Root Command:** The root command adds subcommands to include all of the functionality for the application, mainly module transaction and query commands.
* **App Configurations:** All application-specific values are the responsibility of the application developer, including the `codec` used to marshal requests before relaying them to a node.
* **User Configurations:** Some values are specific to the user, such as the user's address and which node they are connected to.
* **RegisterRoutes Function:** To be passed to an instantiated REST Server so that it knows how to route requests for this particular application.
2 changes: 2 additions & 0 deletions docs/interfaces/query-lifecycle.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@

## Prerequisites

[Introduction to Interfaces](./interfaces-intro.md)

## Synopsis

This document describes SDK interfaces in detail through the lifecycle of a query, from the user interface to application stores and back. The query will be referred to as `query`.
Expand Down
41 changes: 33 additions & 8 deletions docs/interfaces/rest.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,53 @@
## Prerequisites

* [Query Lifecycle](./query-lifecycle.md)
* [Application CLI](./cli.md)

## Synopsis

This document describes how to create a REST interface for an SDK application. A separate document for creating module REST Routes can be found [here](#../module-interfaces.md#rest).

- [Application REST Interface](#application-rest-interface)
- [REST Server](#rest-server)
- [Router](#router)
- [Registering Routes](#registering-routes)

## Application REST Interface

Building a REST Interface for an application involves creating a REST server to route requests and output responses. The SDK has its own REST Server type used for LCDs (light-client daemons). It has a `ServeCommand` that takes in an application's `codec` and `RegisterRoutes` function, starts up a new SDK REST Server, and registers routes using function provided from the application. To enable this command, it should be added as a subcommand of the root command `RootCmd` in the `main()` function of the CLI interface.

Users can use the application CLI to start a new LCD, a local server through which they can securely interact with the application without downloading the entire state. The command entered by users would look something like this:

```bash
appcli rest-server --chain-id <chainID> --trust-node
```

## REST Server

The SDK REST Server has the following:
A REST Server is used to receive and route HTTP Requests, obtain the results from the application, and return the response to the user. The REST Server defined by the SDK LCD package contains the following:

* **Router:** A router for HTTP requests. A new router can be instantiated for an application and used to match routes based on path, request method, headers, etc. The SDK uses the [Gorilla Mux Router](https://github.com/gorilla/mux).
* **CLIContext:** A [`CLIContext`](./query-lifecycle.md#clicontext) created for a user interaction.
* **Keybase:** A [Keybase](../core/keys-accounts.md) is a key manager.
* **Logger:** A logger from Tendermint `Log`, a log package structured around key-value pairs that allows logging level to be set differently for different keys. The logger takes `Debug()`, `Info()`, and `Error()`s.
* **Listener:** A [listener](https://golang.org/pkg/net/#Listener) from the net package.

* **Mux Router**
* **CLIContext**
* **Keybase**
* **Logger**
* **Listener**
Of the five, the only attribute that developers will need to configure is the router.

## Registering Routes

For information about how to define REST Routes for modules, click [here](../building-modules.md#rest)
To include routes for each module in an application, the CLI must have some kind of function to Register Routes in its REST Server. This `RegisterRoutes` function is utilized by the `ServeCommand` and must include routes for each of the application's modules. Since each module used by an SDK application implements a [`RegisterRESTRoutes`](../building-modules.md#rest) function, application developers simply use the Module Manager to call this function for each module.

At the bare minimum, a `RegisterRoutes` function should use the SDK client package `RegisterRoutes` function to be able to route RPC calls, and instruct the application Module Manager to call `RegisterRESTRoutes` for all of its modules:

```go
func registerRoutes(rs *lcd.RestServer) {
client.RegisterRoutes(rs.CliCtx, rs.Mux)
app.ModuleBasics.RegisterRESTRoutes(rs.CliCtx, rs.Mux)
}
```

This function is specific to the application and passed in to the `ServeCommand`, which should be added to the `rootCmd` as such:

```go
rootCmd.AddCommand(lcd.ServeCommand(cdc, registerRoutes))
```

0 comments on commit 0284332

Please sign in to comment.