Go Implementation Short URL project

Source: Internet
Author: User
Tags dsn getmessage

First of all, let's talk about the application scenario for this business:

    1. Convert a long URL to a short URL
    2. Mainly used for micro-blog, QR code, such as the word limit of the scene

The main implementation of the functional analysis:

    1. Convert the address of a long URL to a short URL address
    2. Get the corresponding original long URL address by a short URL
    3. Whether the same long URL address requires the same short URL address

The implementation of this is an API service

Database design

The design of the database is not very complex, either:

Here's a setup that needs to be primarily about the design of the ID in the database table, which needs to be set to the self-increment
And here's a question that needs to be known in advance, our idea is that the value of the ID will be converted to 62 in the code for the binary conversion:

Convert decimal to 62 binary 0-9a-za-Z 62 binary func transTo62 (id Int64) string{1--> 1//10-->a61-->Z CharSet:= "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"var shorturl []bytefor{var resultbyteNumber := ID% 62result=Charset[number] var tmp []bytetmp=Append (tmp,result) Shorturl=Append (Tmp,shorturl ...) ID= ID/62ifid = = 0{Break}} FMT. Println (String (Shorturl)) return string (Shorturl)}

So here we need to set the starting value of the database ID, you can set a large point, so that conversion to 62 after the binary is not too short

Code logic

Project complete code git address: Https://github.com/pythonsite/go_simple_code/tree/master/short_url
Of course, the code here still needs to be optimized later, but here's a simple API function through the Golang built-in Net/http library.

directory Structure of the code

| ____logic| | ____logic.go| ____model| | ____data.go| ____api| | ____api.go| ____client| |____client.go

The logic directory is the primary processing logic
Model is the definition of request and response structure
API directory for the program's entry program
Client for the test request, the conversion of the address

The Model code is:

Package Modeltype long2shortrequest struct {    originurl string ' JSON:"Origin_url"'}type Responseheader struct {    int ' JSON: ' Code ''    message string ' JSON:' message ''}type long2shortresponse struct {    responseheader    shorturl string ' JSON:' short_url ''}type short2longrequest struct {    shorturl string ' JSON:' short_url ''}type short2longresponse struct {    Responseheader    originurl string ' JSON:' Origin_url '}

The code for logic is:

Package Logicimport ("Go_dev/11/short_url/model" "Github.com/jmoiron/sqlx" "FMT" "Crypto/md5" "Database/sql") var (Db*SQLX. db) type Shorturl struct {Id int64 ' DB:"id"' Shorturl string ' DB:"Short_url"' OriginUrl string ' DB:"Origin_url"' Hashcode string ' DB:"Hash_code"'}func initdb (DSN string) (err error) {//database initialization db, err= Sqlx. Open ("MySQL", DSN)ifErr! =nil{FMT. Println ("Connect to MySQL failed:", err) return} Return}func Long2short (req*model. Long2shortrequest) (Response *model. Long2shortresponse, err Error) {Response= &model. long2shortresponse{} URLMD5:= Fmt. Sprintf ("%x", MD5. Sum ([]byte(req. OriginUrl )) var ShortShorturl Err= Db.get (& Short, "Select Id,short_url,origin_url,hash_code from Short_url where hash_code=?", URLMD5)ifErr = =SQL. errnorows{Err=Nil//there is no record in the database, regenerate a new short URL Shorturl,errret:=Generateshorturl (REQ,URLMD5)ifErrret! =nil{Err=Errret Return} response. Shorturl=Shorturl return}ifErr! =nil{Return} response. Shorturl= Short. Shorturl Return}func Generateshorturl (req*model. Long2shortrequest,hashcode string) (Shorturl String,err error) {result,err:= Db.exec ("INSERT into Short_url (Origin_url,hash_code) VALUES (?,?)", req. Originurl,hashcode)ifErr! =nil{return}0-9a-za-Z 62 binary insertid,_:=result. Lastinsertid () Shorturl=transTo62 (insertid) _,err= Db.exec ("Update short_url set short_url=?") where id=? ", Shorturl,insertid)ifErr! =nil{FMT. PRINTLN (ERR) return} return}Convert decimal to 62 binary 0-9a-za-Z 62 binary func transTo62 (id Int64) string{1--> 1//10-->a61-->Z CharSet:= "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"var shorturl []bytefor{var resultbyteNumber := ID% 62result=Charset[number] var tmp []bytetmp=Append (tmp,result) Shorturl=Append (Tmp,shorturl ...) ID= ID/62ifid = = 0{Break}} FMT. Println (String (Shorturl)) return string (Shorturl)}func Short2long (req*model. Short2longrequest) (Response *model. Short2longresponse, err Error) {Response= &model. short2longresponse{} var ShortShorturl Err= Db.get (& Short, "Select Id,short_url,origin_url,hash_code from Short_url where short_url=?", req. Shorturl)ifErr = =SQL. errnorows{Response. Code= 404return}ifErr! =nil{Response. Code= 500return} response. OriginUrl= Short. OriginUrl return}

The code for the API is:

Package Mainimport ("Io/ioutil" "Net/http" "FMT" "Encoding/json" "Go_dev/11/short_url/logic" "Go_dev/11/short_url/model"    _ "Github.com/go-sql-driver/mysql") const (errsuccess= 0Errinvalidparameter= 1001Errserverbusy= 1002) func getMessage (Codeint) (msg string) {switch code { Caseerrsuccess:msg= "Success" Caseerrinvalidparameter:msg= "Invalid Parameter" Caseerrserverbusy:msg= "Server Busy"default:msg= "Unknown Error"} return}//used to return the serialized data, the failed return func responseerror (w http. Responsewriter, Codeint) {var response model. Responseheader Response. Code=Code Response. Message=getMessage (code) data, err:=JSON. Marshal (response)ifErr! =Nil {w.write ([]byte("{\" code\ ": $, \" message\ ": \" Server Busy\ "}") ) return} w.write (data)}//used to return serialized data, a successful return of Func responsesuccess (w http. Responsewriter, Data interface{}) {databyte, err:=JSON. Marshal (data)ifErr! =Nil {w.write ([]byte("{\" code\ ": $, \" message\ ": \" Server Busy\ "}") ) return} w.write (Databyte)}//long address to short address func long2short (w http. Responsewriter, R*http. Request) {//It is necessary to note that the data sent by post is sent over a JSON-formatted data, err:=Ioutil. ReadAll (r.body)ifErr! =Nil {fmt. Println ("Read all failded,", Err) responseerror (W,1001) return} var req model. Long2shortrequest//save deserialized data in struct err= json. Unmarshal (Data, &req)ifErr! =Nil {fmt. Println ("Unmarshal failded,", Err) responseerror (W,1002) return} resp, err:= logic. Long2short (&req)ifErr! =Nil {fmt. Println ("Long2short failded,", Err) responseerror (W,1003) return} responsesuccess (W, resp)}//short address to long address func Short2long (w http. Responsewriter, R*http. Request) {//It is necessary to note that the data sent by post is sent over a JSON-formatted data, err:=Ioutil. ReadAll (r.body)ifErr! =Nil {fmt. Println ("Read all failded,", Err) responseerror (W,1001) return} var req model. Short2longrequest//save deserialized data in struct err= json. Unmarshal (Data, &req)ifErr! =Nil {fmt. Println ("Unmarshal failded,", Err) responseerror (W,1002) return} resp, err:= logic. Short2long (&req)ifErr! =Nil {fmt. Println ("Long2short failded,", Err) responseerror (W,1003) return} responsesuccess (W, resp)}func main () {err:= logic. Initdb ("Root:[email protected" (192.168.50.145:3306)/short_url?parsetime=true ")    ifErr! =nil{FMT. Printf ("Init db failed,err:%v\n", err) return} http. Handlefunc ("/trans/long2short", Long2short) http. Handlefunc ("/trans/short2long", Short2long) http. Listenandserve (": 18888", nil)}

Summary

This time through this small code to go also has a preliminary understanding and use, but also through the net/http package to achieve the function of the API, but also the basic use of a general understanding

Go Implementation Short URL project

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.