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

Swagger Example #55

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
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
35 changes: 17 additions & 18 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,40 +4,39 @@

Each directory contains a standalone [Revel](http://revel.github.io/manual) application, eg

狂欢是好的,保存UTF8 。保持微笑,享受..抱怨..请让它好看
狂欢是好的,保存UTF8 。保持微笑,享受..抱怨..请让它好看


```
git clone https://github.com/revel/examples.git $GOPATH/src/github.com/revel/examples
revel run github.com/revel/examples/booking
```

* [Booking](booking.html)
* [Booking](booking.html)
- A database-driven hotel-booking application, including user management
* [Chat](chat.html)

* [Chat](chat.html)
- A chat room demonstrating active refresh, long-polling (comet), and [websocket](http://revel.github.io/manual/websockets.html) implementations.
* [Validation](validation.html)

* [Validation](validation.html)
- A demonstration of input [validation](http://revel.github.io/manual/validation.html).
* [Upload](upload.html)

* [Upload](upload.html)
- Demonstrates single and multiple file uploads to a webserver via http.
* [Twitter OAuth](twitter-oauth.html)

* [Twitter OAuth](twitter-oauth.html)
- Display `mentions` and allows `posting` to a Twitter account using OAuth.

* [Facebook OAuth2](facebook-oauth2.html)
- Display Facebook user information using OAuth2.



* [Facebook OAuth2](facebook-oauth2.html)
- Display Facebook user information using OAuth2.

* [Swagger](https://github.com/go-swagger/go-swagger)
- Demonstrates how to incorporate go-swagger for spec generation

- If you spot a mistake etc, then let us know
- If you have a good sample application idea, then let us know
- If you got an app, then please make a pull request




- If you spot a mistake etc, then let us know
- If you have a good sample application idea, then let us know
- If you got an app, then please make a pull request
109 changes: 109 additions & 0 deletions swagger/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
Swagger Demo
=========================
The `Swagger` app demonstrates ([browse the source](https://github.com/revel/samples/tree/master/swagger)):

* Using [go-swagger](https://github.com/go-swagger/go-swagger) library to generate a spec based on the [chat](https://github.com/revel/samples/tree/master/chat) example

Here's a quick summary of the structure:
```
swagger/app/
chatroom # Chat room routines
chatroom.go

controllers
app.go # The login screen, allowing user to choose from supported technologies
refresh.go # Handlers for the "Active Refresh" chat demo
longpolling.go # Handlers for the "Long polling" ("Comet") chat demo
websocket.go # Handlers for the "Websocket" chat demo

views
# HTML and Javascript

```
# Swagger Meta

#### Inside of your app/controller/app.go file, at the top put:
*The comment lines are necessary*
```
//go:generate swagger generate spec -o swagger.json
```

#### Make sure you put a blank new line and then add this:
```
// Package classification Some Example API.
// Example API
//
//
//
// Schemes: https
// Host: api.somedomain.com
// BasePath: /
// Version: 1.0.0
// License: MIT http://opensource.org/licenses/MIT
// Contact: Name<[email protected]> https://www.somewhere.com
//
// Consumes:
// - application/json
// - application/x-www-form-urlencoded
//
// Produces:
// - text/html
//
//
//
//
// swagger:meta
```

# Swagger Route

#### Inside each of your controllers and above each route add the following:

```
// swagger:route POST /some/route route description
//
// Route description
//
//
// Consumes:
// - application/x-www-form-urlencoded
//
// Produces:
// - text/html
//
// Schemes: https, http, ws
//
//
// Responses:
// 200: Success
// 401: Invalid Info

// swagger:operation POST /some/route route description
//
// Route Description
//
//
// ---
// produces:
// - text/html
// parameters:
// - name: some_param
// in: formData
// description: example param
// required: true
// type: string
// responses:
// '200':
// description: Success
// '401':
// description: Invalid Info
```

# Generating

#### You will need to cd into the app/controllers directory and then run:
```
go generate
```

This will put a swagger.json file inside of your app/controllers folder. Feel free to add that file to ignore for git and have CI run the go generate on compile and you can now automate Swagger inside of your API.
114 changes: 114 additions & 0 deletions swagger/app/chatroom/chatroom.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
package chatroom

import (
"container/list"
"time"
)

type Event struct {
Type string // "join", "leave", or "message"
User string
Timestamp int // Unix timestamp (secs)
Text string // What the user said (if Type == "message")
}

type Subscription struct {
Archive []Event // All the events from the archive.
New <-chan Event // New events coming in.
}

// Owner of a subscription must cancel it when they stop listening to events.
func (s Subscription) Cancel() {
unsubscribe <- s.New // Unsubscribe the channel.
drain(s.New) // Drain it, just in case there was a pending publish.
}

func newEvent(typ, user, msg string) Event {
return Event{typ, user, int(time.Now().Unix()), msg}
}

func Subscribe() Subscription {
resp := make(chan Subscription)
subscribe <- resp
return <-resp
}

func Join(user string) {
publish <- newEvent("join", user, "")
}

func Say(user, message string) {
publish <- newEvent("message", user, message)
}

func Leave(user string) {
publish <- newEvent("leave", user, "")
}

const archiveSize = 10

var (
// Send a channel here to get room events back. It will send the entire
// archive initially, and then new messages as they come in.
subscribe = make(chan (chan<- Subscription), 10)
// Send a channel here to unsubscribe.
unsubscribe = make(chan (<-chan Event), 10)
// Send events here to publish them.
publish = make(chan Event, 10)
)

// This function loops forever, handling the chat room pubsub
func chatroom() {
archive := list.New()
subscribers := list.New()

for {
select {
case ch := <-subscribe:
var events []Event
for e := archive.Front(); e != nil; e = e.Next() {
events = append(events, e.Value.(Event))
}
subscriber := make(chan Event, 10)
subscribers.PushBack(subscriber)
ch <- Subscription{events, subscriber}

case event := <-publish:
for ch := subscribers.Front(); ch != nil; ch = ch.Next() {
ch.Value.(chan Event) <- event
}
if archive.Len() >= archiveSize {
archive.Remove(archive.Front())
}
archive.PushBack(event)

case unsub := <-unsubscribe:
for ch := subscribers.Front(); ch != nil; ch = ch.Next() {
if ch.Value.(chan Event) == unsub {
subscribers.Remove(ch)
break
}
}
}
}
}

func init() {
go chatroom()
}

// Helpers

// Drains a given channel of any messages.
func drain(ch <-chan Event) {
for {
select {
case _, ok := <-ch:
if !ok {
return
}
default:
return
}
}
}
Loading