Foreword
This project is the work of Zhongshan University School of Science and Computer Data 2019 service computing. All the code will be uploaded to the blog github them.
Github project Address: https://github.com/BlogByFourMan
profile: https://starashzero.github.io
Outline
Our group of four to complete a separate front and rear ends of the web blog application --Simple Blog
currently supported features are:
- registered
- Landed
- View blog
- View comments
- Comment
Description of work
I was responsible for writing API code related to the back-end User in the group
- Project structure:
- db package the relevant code stored database, the database used BoltDB
- model data to be used to store the packet structure
- go package implements the code api
development process
-
db
db achieve database code, database use BoltDB, using a method Key: Value
I realized with User-related database code- GetUser
GetUser implement the query for user information, the input parameters for the username, the output for the User information
by default Username and Password are "" User's identity as a query failsfunc GetUser(username string) model.User { db, err := bolt.Open(GetDBPATH(), 0600, nil) if err != nil { log.Fatal(err) } defer db.Close() user := model.User{ Username: "", Password: "", } err = db.View(func(tx *bolt.Tx) error { b := tx.Bucket([]byte("user")) if b != nil { data := b.Get([]byte(username)) if data != nil { err := json.Unmarshal(data, &user) if err != nil { log.Fatal(err) } } } return nil }) if err != nil { log.Fatal(err) } return user }
- PutUsers
PutUsers realize User data is added, an array of input parameters User (add multiple support), and returns the error messagefunc PutUsers(users []model.User) error { db, err := bolt.Open(GetDBPATH(), 0600, nil) if err != nil { log.Fatal(err) } defer db.Close() err = db.Update(func(tx *bolt.Tx) error { b := tx.Bucket([]byte("user")) if b != nil { for i := 0; i < len(users); i++ { username := users[i].Username data, _ := json.Marshal(users[i]) b.Put([]byte(username), data) } } return nil }) if err != nil { return err } return nil }
- GetUser
-
model
in the development process need to use several data structures- The User
the User is a data structure for storing user information, the relatively simple, only store the user name and passwordtype User struct { Username string `json:"username,omitempty"` Password string `json:"password,omitempty"` }
- The Comment
the Comment class storage comment information, including user comments, article id, comment information, comments, and other contenttype Comment struct { User string `json:"user,omitempty"` ArticleId int64 `json:"article_id,omitempty"` Date string `json:"date,omitempty"` Content string `json:"content,omitempty"` }
- The User
-
Go
Go package implements API code-
response.go
response.go for unitary Response
myResponse structure is used to store information Response
Options treated separately OPTIONS (loken authentication when needed, will receive a packet in advance OPTIONS)
Response to send a reply messagetype MyResponse struct { OkMessage interface{} `json:"ok,omitempty"` ErrorMessage interface{} `json:"error,omitempty"` } func Options(w http.ResponseWriter, r *http.Request){ w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.Header().Set("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Credentials, Access-Control-Allow-Methods, Access-Control-Allow-Headers, Authorization, X-Requested-With") w.Header().Set("Access-Control-Allow-Origin", "*") w.WriteHeader(http.StatusOK) } func Response(response interface{}, w http.ResponseWriter, code int) { jsonData, jErr := json.Marshal(&response) if jErr != nil { log.Fatal(jErr.Error()) } w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.Header().Set("Access-Control-Allow-Methods","PUT,POST,GET,DELETE,OPTIONS") w.Header().Set("Access-Control-Allow-Headers", "Content-Type, Access-Control-Allow-Origin, Access-Control-Allow-Credentials, Access-Control-Allow-Methods, Access-Control-Allow-Headers, Authorization, X-Requested-With") w.Header().Set("Access-Control-Allow-Origin", "*") w.Write(jsonData) w.WriteHeader(code) }
-
api_user.go
api_user.go implement User-related API:- POST /article/{id}/comments
- POST /user/login
- POST /user/register
I am responsible for the development of these three areas, but loken authentication is completed by another crew
- login and register
to achieve much the same login and register- Body which first reads parameters, convert it to a User structure
err := json.NewDecoder(r.Body).Decode(&user)
- User name corresponding to the user information obtained from the database
check := db.GetUser(user.Username)
- User authentication information, such as whether there is a user authentication, and the like corresponding to the account and password are
- Finally, return token
Response(MyResponse{ tokenString, nil, }, w, http.StatusOK)
- CommentPost
add a comment needs to authenticate a user, the main process is as follows:-
Verify that the user token
token, isValid := ValidateToken(w, r)
-
Reading body parameter, and decodes structure Comment
err := json.NewDecoder(r.Body).Decode(&comment)
-
According token update User
if v, ok := token.Claims.(jwt.MapClaims); ok { name, _ := v["name"].(string) comment.User = name }
-
Id for articles
articleId := strings.Split(r.URL.Path, "/")[2] comment.ArticleId, err = strconv.ParseInt(articleId, 10, 64)
-
Generation time
comment.Date = fmt.Sprintf("%d-%d-%d", time.Now().Year(), time.Now().Month(), time.Now().Day())
-
The comments added to the database
for i := 0; i < len(articles); i++ { articles[i].Comments = append(articles[i].Comments, comment) } err = db.PutArticles(articles)
-
Returns the comment data
Response(MyResponse{ comment, nil, }, w, http.StatusOK)
-
- Body which first reads parameters, convert it to a User structure
-