Skip to content

Commit

Permalink
Merge pull request #53 from jirenius/feature/g-52-hello-world-example
Browse files Browse the repository at this point in the history
GH-52: Added 01-hello-world example.
  • Loading branch information
jirenius committed Dec 5, 2019
2 parents ce16943 + 8dea131 commit d4c7221
Show file tree
Hide file tree
Showing 31 changed files with 1,041 additions and 766 deletions.
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,11 @@ func main() {

| Example | Description
| --- | ---
| [Edit Text](examples/edit-text/) | Text field that can be edited by multiple clients concurrently.
| [Edit Text BadgerDB](examples/edit-text-badgerdb/) | Edit Text example using BadgerDB middleware to persist all changes.
| [Book Collection](examples/book-collection/) | List of book titles & authors that can be edited by many.
| [Book Collection BadgerDB](examples/book-collection-badgerdb/) | Book Collection example using BadgerBD middleware to persist all changes.
| [Hello World](examples/01-hello-world/) | Smallest of services serving a static message.
| [Edit Text](examples/02-edit-text/) | Single text field that is updated in real time.
| [Edit Text Persisted](examples/03-edit-text-persisted/) | Edit Text example persisting changes using BadgerDB middleware.
| [Book Collection](examples/04-book-collection/) | List of book titles & authors that can be edited by many.
| [Book Collection Persisted](examples/04-book-collection-persisted/) | Book Collection example persisting changes using BadgerBD middleware.

> **Note**
>
Expand Down
52 changes: 52 additions & 0 deletions examples/01-hello-world/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# Hello World Example

**Tags:** *Models*

## Description
Simple service serving a message to the world.

## Prerequisite

* [Download](https://golang.org/dl/) and install Go
* [Install](https://resgate.io/docs/get-started/installation/) *NATS Server* and *Resgate* (done with 3 docker commands).

## Install and run

```text
git clone https://github.com/jirenius/go-res
cd go-res/examples/01-hello-world
go run main.go
```

## Things to try out

### Access API through HTTP
* Open the browser and go to:
```text
http://localhost:8080/api/example/model
```

### Access API through WebSocket
* Open *Chrome* and go to [resgate.io - resource viewer](https://resgate.io/viewer).
* Type in the resource ID below, and click *View*:
```text
example.model
```
> **Note**
>
> Chrome allows websites to connect to *localhost*, while other browsers may give a security error.
### Real time update on static resource
* Stop the project, and change the `"Hello, World!"` message in *main.go*.
* Restart the project and observe how the message is updated in the viewer (see [above](#access-api-through-websocket)).

### Get resource with ResClient
* In the [resgate.io - resource viewer](https://resgate.io/viewer), open the DevTools console (*Ctrl+Shift+J*).
* Type the following command, and press *Enter*:
```javascript
client.get("example.model").then(m => console.log(m.message));
```
> **Note**
>
> The resource viewer app stores the *ResClient* instance in the global `client` variable, for easy access.
16 changes: 16 additions & 0 deletions examples/01-hello-world/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package main

import res "github.com/jirenius/go-res"

func main() {
s := res.NewService("example")
s.Handle("model",
res.Access(res.AccessGranted),
res.GetModel(func(r res.ModelRequest) {
r.Model(map[string]string{
"message": "Hello, World!",
})
}),
)
s.ListenAndServe("nats://localhost:4222")
}
File renamed without changes.
60 changes: 60 additions & 0 deletions examples/02-edit-text/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Edit Text Example

**Tags:** *Models*, *Call methods*, *Client subscriptions*

## Description
A simple text field that can be edited by multiple clients simultaneously.

## Prerequisite

* [Download](https://golang.org/dl/) and install Go
* [Install](https://resgate.io/docs/get-started/installation/) *NATS Server* and *Resgate* (done with 3 docker commands).

## Install and run

```text
git clone https://github.com/jirenius/go-res
cd go-res/examples/02-edit-text
go run main.go
```

Open the client
```
http://localhost:8082
```

## Things to try out

### Realtime updates
* Open the client in two separate tabs.
* Edit the message in one tab, and observe realtime updates in both.

### System reset
* Stop the service.
* Edit the default text (`"Hello, Go World!"`) in *main.go*.
* Restart the service to observe resetting of the message in all clients.

## API

Request | Resource | Description
--- | --- | ---
*get* | `text.shared` | Simple model.
*call* | `text.shared.set` | Sets the model's *message* property.

## REST API

Resources can be retrieved using ordinary HTTP GET requests, and methods can be called using HTTP POST requests.

### Get model
```
GET http://localhost:8080/api/text/shared
```

### Update model
```
POST http://localhost:8080/api/text/shared/set
```
*Body*
```
{ "message": "Updated through HTTP" }
```
42 changes: 42 additions & 0 deletions examples/02-edit-text/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Edit Text Example</title>
<link rel="icon" href="data:,">
<script src="https://cdn.jsdelivr.net/npm/resclient@latest/dist/resclient.min.js"></script>
</head>
<body>
<p>Try running the client in two separate tabs!</p>
<p>Web resource: <a href="http://localhost:8080/api/text/shared" target="_blank">http://localhost:8080/api/text/shared</a></p>
<hr />
<div id="root"><input id="input" /></div>
<script>
const ResClient = resclient.default;

// Creating the client instance.
let client = new ResClient('ws://localhost:8080');

// Get the model from the service.
client.get('text.shared').then(model => {
// Set value of the input element
input.value = model.message;

// Listen for user input and call set to update the remote model.
input.addEventListener('input', () => {
model.set({ message: input.value });
});

// Listen for model change events.
// The model will be unsubscribed after calling model.off
model.on('change', () => {
input.value = model.message;
});
}).catch(err => {
root.textContent = err.code == 'system.connectionError'
? "Connection error. Are NATS Server and Resgate running?"
: err.message;
});
</script>
</body>
</html>
6 changes: 3 additions & 3 deletions examples/edit-text/main.go → examples/02-edit-text/main.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*
This is an example of a simple text field that can be edited by multiple clients.
* It exposes a single resource: "example.shared".
* It exposes a single resource: "text.shared".
* It allows setting the resource's Message property through the "set" method.
* It resets the model on server restart.
* It serves a web client at http://localhost:8082
Expand All @@ -24,9 +24,9 @@ var shared = &Model{Message: "Hello, Go World!"}

func main() {
// Create a new RES Service
s := res.NewService("example")
s := res.NewService("text")

// Add handlers for "example.shared" resource
// Add handlers for "text.shared" resource
s.Handle("shared",
// Allow everone to access this resource
res.Access(res.AccessGranted),
Expand Down
File renamed without changes.
54 changes: 54 additions & 0 deletions examples/03-edit-text-persisted/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Edit Text Persisted Example

**Tags:** *Models*, *Call methods*, *Client subscriptions*, *Persistence*

## Description
This is the Edit Text example where all changes are persisted using the BadgerDB middleware. With a database middleware, both clients and database can be updated with a single event.

## Prerequisite

* [Download](https://golang.org/dl/) and install Go
* [Install](https://resgate.io/docs/get-started/installation/) *NATS Server* and *Resgate* (done with 3 docker commands).

## Install and run

```text
git clone https://github.com/jirenius/go-res
cd go-res/examples/03-edit-text-persisted
go run main.go
```

Open the client
```
http://localhost:8083
```

## Things to try out

### BadgerDB persistance
Run the client and make edits to the text. Restart the service and observe all changes are persisted.

## API

Request | Resource | Description
--- | --- | ---
*get* | `text.shared` | Simple model.
*call* | `text.shared.set` | Sets the model's *message* property.

## REST API

Resources can be retrieved using ordinary HTTP GET requests, and methods can be called using HTTP POST requests.

### Get model
```
GET http://localhost:8080/api/text/shared
```

### Update model
```
POST http://localhost:8080/api/text/shared/set
```
*Body*
```
{ "message": "Updated through HTTP" }
```
42 changes: 42 additions & 0 deletions examples/03-edit-text-persisted/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8" />
<title>Edit Text Persisted Example</title>
<link rel="icon" href="data:,">
<script src="https://cdn.jsdelivr.net/npm/resclient@latest/dist/resclient.min.js"></script>
</head>
<body>
<p>Try running the client in two separate tabs!</p>
<p>Web resource: <a href="http://localhost:8080/api/text/shared" target="_blank">http://localhost:8080/api/text/shared</a></p>
<hr />
<div id="root"><input id="input" /></div>
<script>
const ResClient = resclient.default;

// Creating the client instance.
let client = new ResClient('ws://localhost:8080');

// Get the model from the service.
client.get('text.shared').then(model => {
// Set value of the input element
input.value = model.message;

// Listen for user input and call set to update the remote model.
input.addEventListener('input', () => {
model.set({ message: input.value });
});

// Listen for model change events.
// The model will be unsubscribed after calling model.off
model.on('change', () => {
input.value = model.message;
});
}).catch(err => {
root.textContent = err.code == 'system.connectionError'
? "Connection error. Are NATS Server and Resgate running?"
: err.message;
});
</script>
</body>
</html>
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
/*
This is the edit-text example with persistance to BadgerDB.
* It exposes a single resource: "example.shared".
* It allows setting the resource's Message property through the "set" method.
This is the Edit Text example where all changes are persisted using the BadgerDB middleware.
* It exposes a single resource: "text.shared".
* It allows setting the resource's message property through the "set" method.
* It persist all changes to BadgerDB.
* It serves a web client at http://localhost:8082
* It serves a web client at http://localhost:8083
*/
package main

Expand All @@ -24,14 +24,14 @@ func main() {
}
defer db.Close()

s := res.NewService("example")
s := res.NewService("text")
s.Handle("shared",
// Define resource type.
res.Model,
// Allow everone to access this resource
res.Access(res.AccessGranted),
// BadgerDB middleware adds a GetResource and ApplyChange handler
middleware.BadgerDB{DB: db, Default: map[string]interface{}{"message": "Resgate loves BadgerDB"}},
middleware.BadgerDB{DB: db, Default: map[string]interface{}{"message": "Hello, BadgerDB!"}},

// Handle setting of the message
res.Set(func(r res.CallRequest) {
Expand All @@ -56,8 +56,8 @@ func main() {

// Run a simple webserver to serve the client.
// This is only for the purpose of making the example easier to run.
go func() { log.Fatal(http.ListenAndServe(":8082", http.FileServer(http.Dir("./")))) }()
log.Println("Client at: http://localhost:8082/")
go func() { log.Fatal(http.ListenAndServe(":8083", http.FileServer(http.Dir("./")))) }()
log.Println("Client at: http://localhost:8083/")

s.ListenAndServe("nats://localhost:4222")
}
File renamed without changes.

0 comments on commit d4c7221

Please sign in to comment.