정리 기능이 있는 바닐라 Go의 실용적인 웹 서버
cgo
) ...내가 정말로 이해하지 못하는 Go 언어 관련 개념이 있습니다.
<-
신호가 POSIX가 아닌 Windows에서 작동합니까?
그리고 내가 싫어하는 것이 분명히 있습니다 ...
// Scoping of error variables.
// Is there a better naming conventions?
// IMO, these kind of namings are very typo-prone.
_, e1 := f1()
if e1 != nil {
log.Fatal(e1)
}
data, e2 := f1()
if e2 != nil {
log.Fatal(e2)
}
요컨대, 그러나 산업과 고용 시장이 그것을 요구합니다.
아직 JSON 직렬화/역직렬화를 수행하지 않았습니다. 미들웨어와 인증은 말할 것도 없습니다. 그러나 나는 커버한다.
req.Query
req.Body
res.Write
package main
import (
"context"
"fmt"
"io/ioutil"
"log"
"net"
"net/http"
"os"
"os/signal"
"syscall"
"time"
)
func main() {
port := os.Getenv("PORT")
if port == "" {
port = "0"
}
listener, err := net.Listen("tcp", "localhost:"+port)
if err != nil {
log.Fatal(err)
}
http.Handle("/", http.FileServer(http.Dir("./dist")))
http.HandleFunc("/api/file", func(w http.ResponseWriter, r *http.Request) {
f := r.URL.Query()["filename"]
if len(f) == 0 {
throwHTTP(&w, fmt.Errorf("filename not supplied"), http.StatusNotFound)
return
}
filename := f[0]
if r.Method == "GET" {
data, eReadFile := ioutil.ReadFile(filename)
if eReadFile != nil {
throwHTTP(&w, eReadFile, http.StatusInternalServerError)
return
}
w.Write(data)
return
} else if r.Method == "PUT" {
data, eReadAll := ioutil.ReadAll(r.Body)
if eReadAll != nil {
throwHTTP(&w, eReadAll, http.StatusInternalServerError)
return
}
eWriteFile := ioutil.WriteFile(filename, data, 0666)
if eWriteFile != nil {
throwHTTP(&w, eWriteFile, http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusCreated)
return
} else if r.Method == "DELETE" {
eRemove := os.Remove(filename)
if eRemove != nil {
throwHTTP(&w, eRemove, http.StatusInternalServerError)
return
}
w.WriteHeader(http.StatusCreated)
return
}
throwHTTP(&w, fmt.Errorf("unsupported method"), http.StatusNotFound)
})
go func() {
// True port will be autogenerated
// And Addr() generated accordingly
log.Println("Listening at:", "http://"+listener.Addr().String())
if err := http.Serve(listener, nil); err != http.ErrServerClosed {
log.Fatal(err)
}
}()
// Cleaning up should be done in 10 seconds
onExit(10 * time.Second)
}
func onExit(timeout time.Duration) {
signals := make(chan os.Signal, 1)
signal.Notify(signals, os.Interrupt, syscall.SIGTERM)
<-signals
log.Println("Cleaning up...")
ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel()
// onExit proper
func() {
time.Sleep(2 * time.Second)
}()
if _, ok := ctx.Deadline(); ok {
log.Println("Clean-up finished. Closing...")
// secs := (time.Until(deadline) + time.Second/2) / time.Second
// log.Printf("Clean-up finished %ds before deadline\n", secs)
} else {
log.Fatal(fmt.Sprintf("Clean-up timeout. Not finished within %ds.", timeout/time.Second))
}
}
func throwHTTP(w *http.ResponseWriter, e error, code int) {
http.Error(*w, e.Error(), code)
log.Println(e, code)
}
cURL로 테스트됨
% PORT=3000 go run .
% curl -i -X PUT --data 'hello' http://127.0.0.1:3000/api/file\?filename\=test.txt
프론트엔드와 연결하는 또 다른 좋은 방법이 있습니다. SQL과 그 매개변수를 보내는 것이 더 나은 방법일 수 있다고 주장할 수 있습니다.
import Loki from 'lokijs'
class LokiRestAdaptor {
loadDatabase (dbname: string, callback: (data: string | null | Error) => void) {
fetch(`/api/file?filename=${encodeURIComponent(dbname)}`)
.then((r) => r.text())
.then((r) => callback(r))
.catch((e) => callback(e))
}
saveDatabase (dbname: string, dbstring: string, callback: (e: Error | null) => void) {
fetch(`/api/file?filename=${encodeURIComponent(dbname)}`, {
method: 'PUT',
body: dbstring
})
.then(() => callback(null))
.catch((e) => callback(e))
}
deleteDatabase (dbname: string, callback: (data: Error | null) => void) {
fetch(`/api/file?filename=${encodeURIComponent(dbname)}`, {
method: 'DELETE'
})
.then(() => callback(null))
.catch((e) => callback(e))
}
}
// eslint-disable-next-line import/no-mutable-exports
export let loki: Loki
export async function initDatabase () {
return new Promise((resolve) => {
loki = new Loki('db.loki', {
adapter: new LokiRestAdaptor(),
autoload: true,
autoloadCallback: () => {
resolve()
},
autosave: true,
autosaveInterval: 4000
})
})
}
Reference
이 문제에 관하여(정리 기능이 있는 바닐라 Go의 실용적인 웹 서버), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://dev.to/patarapolw/practical-web-server-in-vanilla-go-with-clean-up-function-i-don-t-really-know-what-i-am-doing-1nh5텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)