Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

updated slides and README.md #5

Merged
merged 1 commit into from
Oct 15, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
Slides for Ultimate Go Meetup, October 18:

http://go-talks.appspot.com/github.com/kkeuning/goa-react/slides/justgenerate.slide

# Introduction to Goa for Microservices and SPAs
```
go get github.com/kkeuning/goa-react
Expand Down
289 changes: 289 additions & 0 deletions slides/justgenerate.slide
Original file line number Diff line number Diff line change
@@ -0,0 +1,289 @@
Go APIs: Just Generate Everything With Goa
Chicago Ultimate Golang Meetup
18 Oct 2016
Tags: go golang generate goa react redux

Kevin Keuning
Goapher
kkeuning@gmail.com
https://github.com/kkeuning
@keuning

* Qualifications To Speak / My Experience So Far

.image ./gatt.jpg _ 200

- Working with goa daily since January 2016
- In production with goa + React SPA
- Working on a goa plug-in to generate javasccript Redux boilerplate (Reduxa)
- Frequent visitor and occasional contributor to #goa channel on gophers slack
- Huge thanks to Raphael Simon and Brian Ketelsen

* My Stack & Experience
.image ./react-logo.png _ 125
.image ./goa-logo@2x.png _ 100
- React
- Redux
- goa + gorma
- PostgreSQL / Amazon RDS
- Docker + Rancher

* Agenda for the session
- Introduction to goa
- Introduction to gorma
- Extending Goa to generate front-end code (Reduxa)

All source for the session is in github:
.link https://github.com/kkeuning/goa-react

* Alternatives for Building APIs With Go
- Standard library (typically with gorilla/mux or julienschmidt/httprouter)
- Minimalist Go web frameworks (router++)
labstack/echo, goji/goji, gin-gonic/gin, etc.
- Specialized / Opinionated API packages
manyminds/api2go for JSONAPI.org implementation
rs/rest-layer similar to Python's Eve
- Goa: "Generate all the things"
API Design Language
Code Generator (goagen)
Runtime Framework (the goa package)
DSL and Code Generation Plug-ins

* Code Generation
- Popular approach: "I'll just use the standard library"
- Alternative to consider: "Maybe I can just generate everything!"
Rapid development without relying on "magic"
Better standardization of code
Easier refactoring- I can generate again after changes
Use templates to generate structs, helper methods, etc.
Minimize reliance on reflection
Not just for APIs- Generate the client code, documentation, etc.

* Code Generation Tools for Go

- *gRPC:* [[https://github.com/grpc/grpc-go]]
- *Goa:* [[https://goa.design]]
- *gen:* [[https://clipperhouse.github.io/gen/]]
- *Goal:* [[https://colegion.github.io/goal/]]
- *Reform:* [[https://github.com/AlekSi/reform/]]
- dozens more

Why?

Go has powerful text templates built into the *standard* *library*.

Code generation provides a best of both worlds scenario, high productivity without reliance on reflection or adding language features.


* goa - Design First, Then Win

.image ./goa-logo@2x.png

The goa framework can be divided into three parts:

- The goa design language is the built-in DSL that allows describing the design of the microservice.
- The code generator uses the output of the DSL to generate artifacts.
- The goa package provides a complete pluggable framework leveraged by both generated and user code to implement the service.

* Design First

goa uses Go code as its input. This Go code is written using a DSL that makes your design process simple and clear. Nested functions allow for a nice DSL in pure Go.

.code design/adderdesign.go /START OMIT/,/END OMIT/
Yes, those are dot imports! Optional in design files, not used in application code.

* Behind the Scenes

Each of those DSL functions is populating a set of structures that describes your API. Each function understands its current `context` and therefore can provide you with compile and generate-time errors when you're building your DSL incorrectly.

API generation was the first use of goa's DSL engine, but it has since been used for gorma (we'll get to that), and can be considered a general purpose DSL engine.

.image ./gatt.jpg _ 400

* Designing an API

Design code usually lives in the ./design package of your project's root. It consists of one or more Go files (because it's a package) that describe your API.

Design code should have the following parts:

- API Definition
- Resource definition
- Media Type definition
- User Type definition (Payloads for create/update methods)
- Security definition

* API Definition

The basics of your API
- Host information
- License information
- Base path

.code design/api_definition.go /START OMIT/,/END OMIT/


* Media Type Definition

What are you sending in response to requests?

.code design/media_types.go /START OMIT/,/END OMIT/

* User Type Definition

What are you receiving in PUT, PATCH, POST?

.code design/user_types.go /START OMIT/,/END OMIT/

* Media Type Definition Revisited

You can build your media types from user types...

.code design/media_types2.go /START OMIT/,/END OMIT/

* Resource Definition

Routing requests to controllers

.code design/resources.go /START OMIT/,/END OMIT/

* We're Ready To GATT...

`goagen --design=github.com/your/project/design bootstrap`

.image ./gatt.jpg _ 600

* What did you get?

- /app = controllers, routing logic, type conversions, validations
- /js = javascript client for your API
- /swagger = swagger controller and swagger spec
- /schema = JSON schema for the API
- /client = Go client package and CLI for your API
- main.go = wire it all together
- {controller.go} = stubbed controllers for all your resources
- Full swagger definition. Use swagger-api or your favorite swagger service.
- Fully functioning app - just add business logic in the controllers

* Swagger Documentation
.image ./swagger.png _ 900

Experience it live:
.link http://swagger.goa.design


* Gorma

Contributed by Brian Ketelsen (GopherCon, Gopher Academy, Go Time...)

Using the same style as `goa`, add some model definitions to your design package.

Gorma generates the an entire data storage package for your API.

http://goa.design/extend/gorma.html

- Uses github.com/jinzhu/gorm as a lightweight ORM
- Manages migrations
- Can be used for full ORM operations, or just as a nice abstraction to allow you to swap databases
- Use sqlite in dev, PostgreSQL in prod, same code!

* Gorma Features

- Understands `goa` media types, payloads, and views

.code models/bottle.go /START OMIT/,/END OMIT/

* Gorma Features

- Generates conversion functions to convert to and from models to your api's types

.code models/bottle_helper2.go /START OMIT/,/END OMIT/

* Beautiful Helpers

.code models/bottle_helper.go /START OMIT/,/END OMIT/

* My Workflow

- Initial API Design (Take your time to plan it, look at examples.)
- `goagen` with `bootstrap`
- `goagen gen --pkg-path=github.com/goadesign/gorma`
- Review generated swagger documentation of my API (I use bootprint for this)
- Add a bit of code to the controllers and main
- Create a database for gorma
- `go build` and run your API server

Changes required? Update Design & GATT:

- `goagen` again {app, js, swagger, schema, client, main, gorma}
- bootstrap and main won't overwrite your main.go and controllers
- Tip: I use `goagen main -o _scaffolds` to see that generated main and controllers

* Security
- Comprehensive Security DSL
BasicAuthSecurity, APIKeySecurity, JWTSecurity, OAuth2Security, NoSecurity

- JWT Middleware Built In
1. Validates the "Bearer" token present in the "Authorization" header against your key(s)
2. Supports scopes in the DSL for granular security
3. If scopes are defined in the design, will validate them per action

- Just use the DSL to add security to your resources:
Security(JWT, func() { // Use JWT to auth requests to this endpoint
Scope("api:access") // Enforce presence of "api" scope in JWT claims.
})
.link https://auth0.com/blog/2014/12/02/using-json-web-tokens-as-api-keys/
* What else?

- Websockets support
- Middleware
JWT, LogRequest, LogResponse, RequestID,
Recover, Timeout, RequireHeader,
CORS, gzip
- Pluggable loggers, use log15, logrus, anything else.
- Pluggable metrics collection - Prometheus, StatsD, more

* Where can I learn more?
- The documentation and website are very detailed:
.link http://goa.design
- Be aware of what's available across the repositories: goa, examples, goa-cellar, gorma-cellar.
.link https://github.com/goadesign
- Brian Ketelsen's goa + gorma talk to the Tampa Go Meetup, watch it on YouTube. This talk is inspired and based on Brian's content.
.link https://www.youtube.com/watch?v=tCFrgWikEX8
- goa has a small but amazing community. Help is available on gophers slack at #goa.

* The Single Page Application (SPA)
*Client* *Side*
I am using React, but there are fantastic Go options emerging. GopherJS looks exciting combined with Polymer or Vecty.

Universal Javascript (Isomorphic) is supported well by React, and its possible to render server side React using Go servers (go-duktape), but not common yet.

*Server* *Side*
Single Page Apps almost always need an API server. Popular options are Rails, Elixir Phoenix, Node.js, or Go.

This is a sweet spot for goa + gorma. The design + generate workflow enables extremely rapid development of APIs.


* What is Redux?

Dan Abramov's Redux has evolved Facebook's Flux pattern to something more accessible, bringing many functional concepts from Elm into to Javascript.

Redux introduces a single, read-only tree structure to manage state in the browser.

The entire state of the application will be represented by one JavaScript object.*
.caption *Ok, maybe not the entire state, but all of the state you care enough about to manage in the Redux store.

All changes and mutations to the application are explicit. State can only be changed by dispatching an action.

Redux is most popular with React, but works very well with Angular 2.0 also and can be used with other frameworks.

Asynchronous actions can be dispatched to update the client state with data from an API. The Axios promise based http client and Redux thunk middleware work nicely together to make it happen.


* Reduxa: Generate your Redux boilerplate from Goa
.code ./actions.js /START OMIT/,/END OMIT/

* Lets look at some live code...
- Working example of React + Redux + Reduxa as front end to goa-cellar
- goa adder example
- gorma-cellar example (extension of goa-cellar)
- `vegeta` load testing our controllers