.
package main
import (
"database/sql"
"fmt"
"html/template"
"net/http"
"github.com/gorilla/mux"
_ "github.com/go-sql-driver/mysql"
)
type Article struct {
Id uint16
Title, Anons, FullText string
}
var posts = []Article{}
var showPost = Article{}
func index(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles("templates/index.html", "templates/header.html", "templates/footer.html")
if err != nil {
fmt.Fprintf(w, err.Error())
}
db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:8889)/golang") // login:password
if err != nil {
panic(err)
}
defer db.Close()
res, err := db.Query("SELECT * FROM `articles`")
if err != nil {
panic(err)
}
posts = []Article{}
for res.Next() {
var post Article
err = res.Scan(&post.Id, &post.Title, &post.Anons, &post.FullText)
if err != nil {
panic(err)
}
posts = append(posts, post)
}
defer res.Close()
t.ExecuteTemplate(w, "index", posts)
}
func create(w http.ResponseWriter, r *http.Request) {
t, err := template.ParseFiles("templates/create.html", "templates/header.html", "templates/footer.html")
if err != nil {
fmt.Fprintf(w, err.Error())
}
t.ExecuteTemplate(w, "create", nil)
}
func save_article(w http.ResponseWriter, r *http.Request) {
title := r.FormValue("title")
anons := r.FormValue("anons")
full_text := r.FormValue("full_text")
if title == "" || anons == "" || full_text == "" {
fmt.Fprintf(w, "Не все данные заполнены")
} else {
db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:8889)/golang") // login:password
if err != nil {
panic(err)
}
defer db.Close()
insert, err := db.Query(fmt.Sprintf("INSERT INTO `articles` (`title`, `anons`, `full_text`) VALUES ('%s', '%s', '%s')", title, anons, full_text))
if err != nil {
panic(err)
}
defer insert.Close()
http.Redirect(w, r, "/", http.StatusSeeOther)
}
}
func show_post(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
// w.WriteHeader(http.StatusOK) // не обязательно
// fmt.Fprintf(w, "ID: %v\n", vars["id"]) // vars["id"] comes from the route
t, err := template.ParseFiles("templates/show.html", "templates/header.html", "templates/footer.html")
if err != nil {
fmt.Fprintf(w, err.Error())
}
db, err := sql.Open("mysql", "root:root@tcp(127.0.0.1:8889)/golang") // login:password
if err != nil {
panic(err)
}
defer db.Close()
res, err := db.Query(fmt.Sprintf("SELECT * FROM `articles` WHERE `id` = '%s'", vars["id"]))
if err != nil {
panic(err)
}
showPost = Article{}
for res.Next() {
var post Article
err = res.Scan(&post.Id, &post.Title, &post.Anons, &post.FullText)
if err != nil {
panic(err)
}
showPost = post
}
defer res.Close()
t.ExecuteTemplate(w, "show", showPost)
}
func handleFunc() {
rtr := mux.NewRouter() // github.com/gorilla/mux
rtr.HandleFunc("/", index).Methods("GET") // Methods("GET", "POST")
rtr.HandleFunc("/create", create).Methods("GET")
rtr.HandleFunc("/save_article", save_article).Methods("POST")
rtr.HandleFunc("/post/{id:[0-9]+}", show_post).Methods("GET")
http.Handle("/", rtr)
http.Handle("/static/", http.StripPrefix("/static/", http.FileServer(http.Dir("./static/"))))
// http.HandleFunc("/", index)
// http.HandleFunc("/create", create)
// http.HandleFunc("/save_article", save_article)
http.ListenAndServe(":8080", nil)
}
func main() {
handleFunc()
}
.
package main
import (
"database/sql"
"encoding/json"
"log"
"net/http"
"os"
"github.com/gorilla/mux"
_ "github.com/lib/pq"
)
type User struct {
ID int `json:"id"`
Name string `json:"name"`
Email string `json:"email"`
}
func main() {
db, err := sql.Open("postgres", os.Getenv("DATABASE_URL"))
if err != nil {
log.Fatal(err)
}
defer db.Close()
_, err = db.Exec("CREATE TABLE IF NOT EXISTS users(id serial primary key, name TEXT, email TEXT)")
if err != nil {
log.Fatal(err)
}
router := mux.NewRouter()
router.HandleFunc("/users", getUsers(db)).Methods("GET")
router.HandleFunc("/users/{id}", getUser(db)).Methods("GET")
router.HandleFunc("/users", createUser(db)).Methods("POST")
router.HandleFunc("/users/{id}", updateUser(db)).Methods("PUT")
router.HandleFunc("/users/{id}", deleteUser(db)).Methods("DELETE")
log.Fatal(http.ListenAndServe(":8000", jsonContentTypeMiddleware(router)))
}
func jsonContentTypeMiddleware(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")
next.ServeHTTP(w, r)
})
}
func getUsers(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
rows, err := db.Query("SELECT * from users")
if err != nil {
log.Fatal(err)
}
defer rows.Close()
users := []User{}
for rows.Next() {
var u User
if err := rows.Scan(&u.ID, &u.Name, &u.Email); err != nil {
log.Fatal(err)
}
users = append(users, u)
}
if err := rows.Err(); err != nil {
log.Fatal(err)
}
json.NewEncoder(w).Encode(users)
}
}
func getUser(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id := vars["id"]
var u User
err := db.QueryRow("SELECT * FROM users WHERE id = $1", id).Scan(&u.ID, &u.Name, &u.Email)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
}
json.NewEncoder(w).Encode(u)
}
}
func createUser(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var u User
json.NewDecoder(r.Body).Decode(&u)
err := db.QueryRow("INSERT INTO users (name, email) VALUES ($1, $2) RETURNING id", u.Name, u.Email)
if err != nil {
log.Fatal(err)
}
json.NewEncoder(w).Encode(u)
}
}
func updateUser(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
var u User
json.NewDecoder(r.Body).Decode(&u)
vars := mux.Vars(r)
id := vars["id"]
_, err := db.Exec("UPDATE users SET name = $1, email = $2 WHERE id = $3", u.Name, u.Email, id)
if err != nil {
log.Fatal(err)
}
json.NewEncoder(w).Encode(u)
}
}
func deleteUser(db *sql.DB) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
id := vars["id"]
var u User
err := db.QueryRow("SELECT * FROM users WHERE id = $1", id).Scan(&u.ID, &u.Name, &u.Email)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
} else {
_, err := db.Exec("DELETE FROM users WHERE id = $1", id)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
}
}
json.NewEncoder(w).Encode("User deleted")
}
}
.
version: '3.9'
services:
go-app:
container_name: go-app
image: somename/go-app:1.0.0
build: .
environment:
DATABASE_URL: "host=go_db user=postgres password=postgres dbname=postgres sslmode=disable"
ports:
- "8000:8000"
depends_on:
go_db:
condition: service_healthy
go_db:
container_name: go_db
image: postgres:12
environment:
POSTGRES_PASSWORD: postgres
POSTGRES_USER: postgres
POSTGRES_DB: postgres
ports:
- "5432:5432"
volumes:
- pgdata:/var/lib/postgresql/data
healthcheck:
test: ["CMD-SHELL", "pg_isready -U postgres"]
interval: 10s
timeout: 5s
retries: 5
volumes:
pgdata: {}
.
FROM golang:1.16.3-alpine3.13
WORKDIR /app
COPY . .
RUN go get -d -v ./...
RUN go build -o playground .
EXPOSE 8000
CMD ["./playground"]