From 78de7ed98abff93fe5fef94907bcfa4f76dcef07 Mon Sep 17 00:00:00 2001 From: Steve Manuel Date: Sat, 27 May 2017 10:27:51 -0700 Subject: adding docs to repo --- docs/build/References/Overview/index.html | 1163 +++++++++++++++++++++++++++++ 1 file changed, 1163 insertions(+) create mode 100644 docs/build/References/Overview/index.html (limited to 'docs/build/References') diff --git a/docs/build/References/Overview/index.html b/docs/build/References/Overview/index.html new file mode 100644 index 0000000..6766130 --- /dev/null +++ b/docs/build/References/Overview/index.html @@ -0,0 +1,1163 @@ + + + + + + + + + + + + + + + + + + References in Ponzu + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ +
+ + +
+
+ + +
+
+
+ +
+
+
+ + +
+
+
+ + +
+
+
+ + +
+
+ + + +

Overview

+ +

References in Ponzu allow you to create relationships between your Content types. +Ponzu uses an embedded database, rather than a more traditional relational database +with SQL support. This may seem unnatural since there is no native concept of +"foreign keys" or "joins" like you may be used to. Instead, Ponzu wires up your +data using references, which are simply URL paths, like /api/content?type=Post&id=1

+

A foreign key as a URL path?! Am I crazy? No! For the purpose Ponzu serves, +this structure works quite well, especially given its creation was specifically +tuned for HTTP/2 features such as "Request/Response Multiplexing" and "Server Push."

+

There is a deeper dive into the HTTP/2 concepts below, but first we'll walk through +a quick tutorial on Ponzu's references.

+

To generate references from the CLI, please read through the documentation. +The example below assumes you understand the syntax.

+
+

Create Your Content Types

+

Here we are creating two Content types, Author and Book. A Book will keep +a reference to an Author in the sense that an author wrote the book.

+
$ ponzu gen c author name:string photo:string:file bio:string:textarea
+$ ponzu gen c book title:string author:@author,name pages:int year:int
+
+ + +

The structs generated for each look like:

+

content/author.go

+
type Author struct {
+    item.Item
+
+    Name  string `json:"name"`
+    Photo string `json:"photo"`
+    Bio   string `json:"bio"`
+}
+
+ + +

content/book.go

+
type Book struct {
+    item.Item
+
+    Title  string `json:"title"`
+    Author string `json:"author"`
+    Pages  int    `json:"pages"`
+    Year   int    `json:"year"`
+}
+
+ + +

Notice how the Author field within the Book struct is a string type, not +an Author type. This is because the Author is stored as a string in our +database, as a reference to the Author, instead of embedding the Author data +inside the Book.

+

Some example JSON data for the two structs looks like:

+

GET /api/content?type=Author&id=1 (Author)

+
{
+    "data": [
+        {
+            "uuid": "024a5797-e064-4ee0-abe3-415cb6d3ed18",
+            "id": 1,
+            "slug": "item-id-024a5797-e064-4ee0-abe3-415cb6d3ed18",
+            "timestamp": 1493926453826,
+            "updated": 1493926453826,
+            "name": "Shel Silverstein",
+            "photo": "/api/uploads/2017/05/shel-silverstein.jpg",
+            "bio": "Sheldon Allan Silverstein was an American poet..."
+        }
+    ]
+}
+
+ + +

GET /api/content?type=Book&id=1 (Book)

+
{
+    "data": [
+        {
+            "uuid": "024a5797-e064-4ee0-abe3-415cb6d3ed18",
+            "id": 1,
+            "slug": "item-id-024a5797-e064-4ee0-abe3-415cb6d3ed18",
+            "timestamp": 1493926453826,
+            "updated": 1493926453826,
+            "title": "The Giving Tree",
+            "author": "/api/content?type=Author&id=1",
+            "pages": 57,
+            "year": 1964
+        }
+    ]
+}
+
+ + +

As you can see, the Author is a reference as the author field in the JSON +response for a Book. When you're building your client, you need to make a second +request for the Author, to the URL path found in the author field of the Book +response.

+

For example, in pseudo-code:

+
# Request 1: 
+$book = GET /api/content?type=Book&id=1
+
+# Request 2: 
+$author = GET $book.author # where author = /api/content?type=Author&id=1
+
+ + +

Until recently, this would be considered bad practice and would be costly to do +over HTTP. However, with the wide availability of HTTP/2 clients, including all +modern web browsers, mobile devices, and HTTP/2 libraries in practically every +programming language, this pattern is fast and scalable.

+
+

Designed For HTTP/2

+

At this point, you've likely noticed that you're still making two independent +HTTP requests to your Ponzu server. Further, if there are multiple references or more +than one item, you'll be making many requests -- how can that be efficient?

+

There are two main concepts at play: Request/Response Multiplexing and Server Push.

+

Request/Response Multiplexing

+

With HTTP/2, a client and server (peers) transfer data over a single TCP connection, +and can send data back and forth at the same time. No longer does a request need +to wait to be sent until after an expected response is read. This means that HTTP +requests can be sent much faster and at the same time on a single connection. +Where previously, a client would open up several TCP connections, the re-use of a +single connection reduces CPU overhead and makes the server more efficient.

+

This feature is automatically provided to you when using HTTP/2 - the only +requirement is that you connect via HTTPS and have active TLS certificates, which +you can get for free by running Ponzu with the --https flag and configuring it +with a properly set, active domain name of your own.

+

Server Push

+

Another impactful feature of HTTP/2 is "Server Push": the ability to preemptively +send a response from the server to a client without waiting for a request. This +is where Ponzu's reference design really shows it's power. Let's revisit the +example from above:

+
# Request 1: 
+$book = GET /api/content?type=Book&id=1
+
+# Request 2: 
+$author = GET $book.author # where author = /api/content?type=Author&id=1
+
+ + +

Instead of waiting for the server to respond with the data for $book.author, +the response data is already in the client's cache before we even make the request! +Now there is no round-trip made to the server and back, and the client reads the +pushed response from cache in fractions of a millisecond.

+

But, how does the server know which response to push and when? You'll need to +specify which fields of the type you've requested should be pushed. This is done +by implementing the item.Pushable interface. +See the example below which demonstrates a complete implementation on the Book +struct, which has a reference to an Author.

+
Example
+

content/book.go

+
...
+type Book struct {
+    item.Item
+
+    Title  string `json:"title"`
+    Author string `json:"author"`
+    Pages  int    `json:"pages"`
+    Year   int    `json:"year"`
+}
+
+
+func (b *Book) Push() []string {
+    return []string{
+        // the json struct tag is used to tell the server which
+        // field(s) it should push - only URL paths originating
+        // from your server can be pushed!
+        "author", 
+    }
+}
+...
+
+ + +

Now, whenever a single Book is requested, the server will preemptively push the +Author referenced by the book. The response for the Author will already be +on the client and will remain there until a request for the referenced Author +has been made.

+
+

What else can I Push?

+

Only fields that are URL paths originating from your server can be pushed. +This means that you could also implement item.Pushable on the Author +type, and return []string{"photo"} to push the Author's image!

+
+
+

Other Considerations

+

HTTP/2 Server Push is a powerful feature, but it can be abused just like anything +else. To try and help mitigate potential issues, Ponzu has put some "stop-gaps" +in place. Server Push is only activated on single item API responses, so you +shouldn't expect to see references or files pushed from the /api/contents endpoint. +An exception to this is the /api/search endpoint, which only the first +result is pushed (if applicable) no matter how many items are in the response.

+

You should take advantage of HTTP/2 in Ponzu and get the most out of the system. +With the automatic HTTPS feature, there is no reason not to and you gain the +additional benefit of encrypting your traffic - which your users will appreciate!

+ + + + + + + +
+
+
+
+ + + + +
+ + + + + + + + + + + + \ No newline at end of file -- cgit v1.2.3