first tests of swagger api documentation

This commit is contained in:
gempir 2018-12-22 09:20:34 +01:00
parent 6c27abad32
commit e6403ef68c
6 changed files with 310 additions and 10 deletions

View file

@ -16,6 +16,9 @@ import (
jsoniter "github.com/json-iterator/go"
"github.com/labstack/echo"
"github.com/labstack/echo/middleware"
_ "github.com/gempir/justlog/docs"
"github.com/swaggo/echo-swagger"
)
type Server struct {
@ -53,8 +56,9 @@ func (s *Server) Init() {
e.Use(middleware.CORSWithConfig(DefaultCORSConfig))
e.GET("/", func(c echo.Context) error {
return c.String(http.StatusOK, "Welcome to justlog")
return c.Redirect(http.StatusMovedPermanently, "/index.html")
})
e.GET("/*", echoSwagger.WrapHandler)
e.GET("/channelid", s.getAllChannels)
e.GET("/channel/:channel/user/:username/range", s.getUserLogsRangeByName)
@ -101,6 +105,10 @@ type chatMessage struct {
Type twitch.MessageType `json:"type"`
}
type errorResponse struct {
Message string `json:"message"`
}
type timestamp struct {
time.Time
}
@ -226,5 +234,5 @@ func shouldReverse(c echo.Context) bool {
func shouldRespondWithJson(c echo.Context) bool {
_, ok := c.QueryParams()["json"]
return c.Request().Header.Get("Content-Type") == "application/json" || c.QueryParam("type") == "json" || ok
return c.Request().Header.Get("Content-Type") == "application/json" || c.Request().Header.Get("accept") == "application/json" || c.QueryParam("type") == "json" || ok
}

View file

@ -55,7 +55,7 @@ func (s *Server) getUserLogsRangeByName(c echo.Context) error {
userMap, err := s.helixClient.GetUsersByUsernames([]string{channel, username})
if err != nil {
log.Error(err)
return c.JSON(http.StatusInternalServerError, "Failure fetching userIDs")
return c.JSON(http.StatusInternalServerError, errorResponse{"Failure fetching userIDs"})
}
names := c.ParamNames()
@ -79,7 +79,7 @@ func (s *Server) getUserLogsByName(c echo.Context) error {
userMap, err := s.helixClient.GetUsersByUsernames([]string{channel, username})
if err != nil {
log.Error(err)
return c.JSON(http.StatusInternalServerError, "Failure fetching userIDs")
return c.JSON(http.StatusInternalServerError, errorResponse{"Failure fetching userIDs"})
}
names := c.ParamNames()
@ -96,6 +96,15 @@ func (s *Server) getUserLogsByName(c echo.Context) error {
return s.getUserLogs(c)
}
// getRandomQuoteByName godoc
// @Summary Get a random chat message from a user
// @tags user
// @Produce json
// @Produce plain
// @Param channel path string true "channelname"
// @Param username path string true "username"
// @Success 200 {object} api.RandomQuoteJSON json
// @Router /channel/{channel}/user/{username}/random [get]
func (s *Server) getRandomQuoteByName(c echo.Context) error {
channel := strings.ToLower(c.Param("channel"))
username := strings.ToLower(c.Param("username"))
@ -103,7 +112,7 @@ func (s *Server) getRandomQuoteByName(c echo.Context) error {
userMap, err := s.helixClient.GetUsersByUsernames([]string{channel, username})
if err != nil {
log.Error(err)
return c.JSON(http.StatusInternalServerError, "Failure fetching userIDs")
return c.JSON(http.StatusInternalServerError, errorResponse{"Failure fetching userIDs"})
}
names := c.ParamNames()
@ -156,18 +165,18 @@ func (s *Server) getUserLogs(c echo.Context) error {
year, err := strconv.Atoi(yearStr)
if err != nil {
log.Error(err)
return c.JSON(http.StatusInternalServerError, "Invalid year")
return c.JSON(http.StatusInternalServerError, errorResponse{"Invalid year"})
}
month, err := strconv.Atoi(monthStr)
if err != nil {
log.Error(err)
return c.JSON(http.StatusInternalServerError, "Invalid month")
return c.JSON(http.StatusInternalServerError, errorResponse{"Invalid month"})
}
logMessages, err := s.fileLogger.ReadLogForUser(channelID, userID, year, month)
if err != nil {
log.Error(err)
return c.JSON(http.StatusInternalServerError, "Failure reading log")
return c.JSON(http.StatusInternalServerError, errorResponse{"Failure reading log"})
}
if shouldReverse(c) {
@ -204,7 +213,7 @@ func (s *Server) getUserLogsRange(c echo.Context) error {
fromTime, toTime, err := parseFromTo(c.QueryParam("from"), c.QueryParam("to"), userHourLimit)
if err != nil {
return c.JSON(http.StatusInternalServerError, err.Error())
return c.JSON(http.StatusInternalServerError, errorResponse{err.Error()})
}
var logMessages []string
@ -218,7 +227,7 @@ func (s *Server) getUserLogsRange(c echo.Context) error {
}
if len(logMessages) == 0 {
return c.JSON(http.StatusNotFound, "No logs found")
return c.JSON(http.StatusNotFound, errorResponse{"No logs found"})
}
if shouldReverse(c) {

128
docs/docs.go Normal file
View file

@ -0,0 +1,128 @@
// GENERATED BY THE COMMAND ABOVE; DO NOT EDIT
// This file was generated by swaggo/swag at
// 2018-12-22 09:19:57.462511 +0100 CET m=+0.035218867
package docs
import (
"bytes"
"github.com/alecthomas/template"
"github.com/swaggo/swag"
)
var doc = `{
"swagger": "2.0",
"info": {
"description": "API for twitch logs",
"title": "justlog API",
"contact": {
"name": "gempir",
"url": "https://gempir.com",
"email": "gempir.dev@gmail.com"
},
"license": {
"name": "MIT",
"url": "https://github.com/gempir/justlog/blob/master/LICENSE"
},
"version": "1.0"
},
"host": "api.gempir.com",
"basePath": "/",
"paths": {
"/channel/{channel}/user/{username}/random": {
"get": {
"produces": [
"application/json",
"text/plain"
],
"tags": [
"user"
],
"summary": "Get a random chat message from a user",
"parameters": [
{
"type": "string",
"description": "channelname",
"name": "channel",
"in": "path",
"required": true
},
{
"type": "string",
"description": "username",
"name": "username",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"$ref": "#/definitions/api.RandomQuoteJSON"
}
}
}
}
}
},
"definitions": {
"api.RandomQuoteJSON": {
"type": "object",
"properties": {
"channel": {
"type": "string"
},
"displayName": {
"type": "string"
},
"message": {
"type": "string"
},
"timestamp": {
"type": "object",
"$ref": "#/definitions/api.timestamp"
},
"username": {
"type": "string"
}
}
},
"api.timestamp": {
"type": "object"
}
}
}`
type swaggerInfo struct {
Version string
Host string
BasePath string
Title string
Description string
}
// SwaggerInfo holds exported Swagger Info so clients can modify it
var SwaggerInfo swaggerInfo
type s struct{}
func (s *s) ReadDoc() string {
t, err := template.New("swagger_info").Parse(doc)
if err != nil {
return doc
}
var tpl bytes.Buffer
if err := t.Execute(&tpl, SwaggerInfo); err != nil {
return doc
}
return tpl.String()
}
func init() {
swag.Register(swag.Name, &s{})
}

84
docs/swagger/swagger.json Normal file
View file

@ -0,0 +1,84 @@
{
"swagger": "2.0",
"info": {
"description": "API for twitch logs",
"title": "justlog API",
"contact": {
"name": "gempir",
"url": "https://gempir.com",
"email": "gempir.dev@gmail.com"
},
"license": {
"name": "MIT",
"url": "https://github.com/gempir/justlog/blob/master/LICENSE"
},
"version": "1.0"
},
"host": "api.gempir.com",
"basePath": "/",
"paths": {
"/channel/{channel}/user/{username}/random": {
"get": {
"produces": [
"application/json",
"text/plain"
],
"tags": [
"user"
],
"summary": "Get a random chat message from a user",
"parameters": [
{
"type": "string",
"description": "channelname",
"name": "channel",
"in": "path",
"required": true
},
{
"type": "string",
"description": "username",
"name": "username",
"in": "path",
"required": true
}
],
"responses": {
"200": {
"description": "OK",
"schema": {
"type": "object",
"$ref": "#/definitions/api.RandomQuoteJSON"
}
}
}
}
}
},
"definitions": {
"api.RandomQuoteJSON": {
"type": "object",
"properties": {
"channel": {
"type": "string"
},
"displayName": {
"type": "string"
},
"message": {
"type": "string"
},
"timestamp": {
"type": "object",
"$ref": "#/definitions/api.timestamp"
},
"username": {
"type": "string"
}
}
},
"api.timestamp": {
"type": "object"
}
}
}

57
docs/swagger/swagger.yaml Normal file
View file

@ -0,0 +1,57 @@
basePath: /
definitions:
api.RandomQuoteJSON:
properties:
channel:
type: string
displayName:
type: string
message:
type: string
timestamp:
$ref: '#/definitions/api.timestamp'
type: object
username:
type: string
type: object
api.timestamp:
type: object
host: api.gempir.com
info:
contact:
email: gempir.dev@gmail.com
name: gempir
url: https://gempir.com
description: API for twitch logs
license:
name: MIT
url: https://github.com/gempir/justlog/blob/master/LICENSE
title: justlog API
version: "1.0"
paths:
/channel/{channel}/user/{username}/random:
get:
parameters:
- description: channelname
in: path
name: channel
required: true
type: string
- description: username
in: path
name: username
required: true
type: string
produces:
- application/json
- text/plain
responses:
"200":
description: OK
schema:
$ref: '#/definitions/api.RandomQuoteJSON'
type: object
summary: Get a random chat message from a user
tags:
- user
swagger: "2.0"

14
main.go
View file

@ -28,6 +28,20 @@ type config struct {
LogLevel string `json:"logLevel"`
}
// @title justlog API
// @version 1.0
// @description API for twitch logs
// @contact.name gempir
// @contact.url https://gempir.com
// @contact.email gempir.dev@gmail.com
// @license.name MIT
// @license.url https://github.com/gempir/justlog/blob/master/LICENSE
// @host api.gempir.com
// @BasePath /
func main() {
startTime := time.Now()