In the previous article, we set up the basic login and registration function with Golang. In today’s article, we will complete a basic webserver with Golang by writing additional features, delete, edit, read (CRUD).
For convenience, let’s review the application’s directory structure.
The full source code you can refer to on Github
1. Middlewares
Like the concept of middlewares
in many other platforms, the middlewares
in webserver golang is a processing function, the code is between receiving request
and returning response
to the client. The tasks that middlewares
usually undertake are user authentication, request filtering (avoiding malicious requests), data validation, etc.
In this article, we will mainly use middlewares
authenticate tokens sent from clients, to authenticate users whether they are entitled to add, delete, edit or view?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | <span class="token comment">// middlewares/check-jwt.go</span> <span class="token keyword">package</span> middlewares <span class="token keyword">import</span> <span class="token punctuation">(</span> <span class="token string">"errors"</span> <span class="token string">"net/http"</span> <span class="token string">"github.com/julienschmidt/httprouter"</span> <span class="token string">"github.com/conglt10/web-golang/auth"</span> <span class="token string">"github.com/conglt10/web-golang/utils"</span> <span class="token punctuation">)</span> <span class="token keyword">func</span> <span class="token function">CheckJwt</span> <span class="token punctuation">(</span> next httprouter <span class="token punctuation">.</span> Handle <span class="token punctuation">)</span> httprouter <span class="token punctuation">.</span> Handle <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token keyword">func</span> <span class="token punctuation">(</span> w http <span class="token punctuation">.</span> ResponseWriter <span class="token punctuation">,</span> r <span class="token operator">*</span> http <span class="token punctuation">.</span> Request <span class="token punctuation">,</span> ps httprouter <span class="token punctuation">.</span> Params <span class="token punctuation">)</span> <span class="token punctuation">{</span> err <span class="token operator">:=</span> jwt <span class="token punctuation">.</span> <span class="token function">Verify</span> <span class="token punctuation">(</span> r <span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> res <span class="token punctuation">.</span> <span class="token function">ERROR</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">401</span> <span class="token punctuation">,</span> errors <span class="token punctuation">.</span> <span class="token function">New</span> <span class="token punctuation">(</span> <span class="token string">"Unauthorized"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> <span class="token function">next</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> r <span class="token punctuation">,</span> ps <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
The above code is a bit complicated, we will gradually learn shortly.
httprouter.Handle Method
We remember in the previous article, httprouter has methods to handle HTTP Methods that the client sends to the server such as GET
, POST
, …
1 2 3 4 5 6 | <span class="token comment">// main.go</span> router <span class="token operator">:=</span> httprouter <span class="token punctuation">.</span> <span class="token function">New</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> router <span class="token punctuation">.</span> <span class="token function">POST</span> <span class="token punctuation">(</span> <span class="token string">"/auth/login"</span> <span class="token punctuation">,</span> routes <span class="token punctuation">.</span> Login <span class="token punctuation">)</span> router <span class="token punctuation">.</span> <span class="token function">POST</span> <span class="token punctuation">(</span> <span class="token string">"/auth/register"</span> <span class="token punctuation">,</span> routes <span class="token punctuation">.</span> Register <span class="token punctuation">)</span> |
1 2 3 4 5 6 7 8 | <span class="token comment">// prototype của cách method</span> <span class="token keyword">func</span> <span class="token punctuation">(</span> r <span class="token operator">*</span> Router <span class="token punctuation">)</span> <span class="token function">GET</span> <span class="token punctuation">(</span> path <span class="token builtin">string</span> <span class="token punctuation">,</span> handle Handle <span class="token punctuation">)</span> <span class="token keyword">func</span> <span class="token punctuation">(</span> r <span class="token operator">*</span> Router <span class="token punctuation">)</span> <span class="token function">POST</span> <span class="token punctuation">(</span> path <span class="token builtin">string</span> <span class="token punctuation">,</span> handle Handle <span class="token punctuation">)</span> <span class="token keyword">func</span> <span class="token punctuation">(</span> r <span class="token operator">*</span> Router <span class="token punctuation">)</span> <span class="token function">PUT</span> <span class="token punctuation">(</span> path <span class="token builtin">string</span> <span class="token punctuation">,</span> handle Handle <span class="token punctuation">)</span> <span class="token keyword">func</span> <span class="token punctuation">(</span> r <span class="token operator">*</span> Router <span class="token punctuation">)</span> <span class="token function">DELETE</span> <span class="token punctuation">(</span> path <span class="token builtin">string</span> <span class="token punctuation">,</span> handle Handle <span class="token punctuation">)</span> <span class="token keyword">func</span> <span class="token punctuation">(</span> r <span class="token operator">*</span> Router <span class="token punctuation">)</span> <span class="token function">HEAD</span> <span class="token punctuation">(</span> path <span class="token builtin">string</span> <span class="token punctuation">,</span> handle Handle <span class="token punctuation">)</span> <span class="token keyword">func</span> <span class="token punctuation">(</span> r <span class="token operator">*</span> Router <span class="token punctuation">)</span> <span class="token function">PATCH</span> <span class="token punctuation">(</span> path <span class="token builtin">string</span> <span class="token punctuation">,</span> handle Handle <span class="token punctuation">)</span> |
In fact, the above methods are a shorter and more convenient way of writing the Handle
method
1 2 3 4 5 6 7 8 9 | <span class="token comment">// Prototype</span> <span class="token keyword">func</span> <span class="token punctuation">(</span> r <span class="token operator">*</span> Router <span class="token punctuation">)</span> <span class="token function">Handle</span> <span class="token punctuation">(</span> method <span class="token punctuation">,</span> path <span class="token builtin">string</span> <span class="token punctuation">,</span> handle Handle <span class="token punctuation">)</span> <span class="token comment">// GET</span> router <span class="token punctuation">.</span> <span class="token function">Handle</span> <span class="token punctuation">(</span> http <span class="token punctuation">.</span> MethodGet <span class="token punctuation">,</span> path <span class="token punctuation">,</span> handle <span class="token punctuation">)</span> <span class="token comment">// POST</span> router <span class="token punctuation">.</span> <span class="token function">Handle</span> <span class="token punctuation">(</span> http <span class="token punctuation">.</span> MethodPost <span class="token punctuation">,</span> path <span class="token punctuation">,</span> handle <span class="token punctuation">)</span> <span class="token comment">// ...</span> |
Type Handle
In the above section, the last parameter of the method is the Handle
data type
1 2 3 | <span class="token comment">// Prototype</span> <span class="token keyword">type</span> Handle <span class="token keyword">func</span> <span class="token punctuation">(</span> http <span class="token punctuation">.</span> ResponseWriter <span class="token punctuation">,</span> <span class="token operator">*</span> http <span class="token punctuation">.</span> Request <span class="token punctuation">,</span> Params <span class="token punctuation">)</span> |
So functions with input parameters in the above form will be treated as a Handle
functions. You know why the parameter http.Request
is in the form of a pointer? The reason is that the data of the request sent from the client can be processed by a series of Handle
functions (such as string middlewares). Therefore, the data needs to be changed directly via the cursor instead of making a copy and changing on it.
1 2 3 4 5 6 7 8 | <span class="token keyword">func</span> <span class="token function">Login</span> <span class="token punctuation">(</span> w http <span class="token punctuation">.</span> ResponseWriter <span class="token punctuation">,</span> r <span class="token operator">*</span> http <span class="token punctuation">.</span> Request <span class="token punctuation">,</span> <span class="token boolean">_</span> httprouter <span class="token punctuation">.</span> Params <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ...</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">Register</span> <span class="token punctuation">(</span> w http <span class="token punctuation">.</span> ResponseWriter <span class="token punctuation">,</span> r <span class="token operator">*</span> http <span class="token punctuation">.</span> Request <span class="token punctuation">,</span> <span class="token boolean">_</span> httprouter <span class="token punctuation">.</span> Params <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token comment">// ...</span> <span class="token punctuation">}</span> |
Summarizing
The CheckJwt
Middlewares above will have the task of Verify
token sent by the client, if the token is invalid, it will return an error. Otherwise, the next processing function (Handle) will be called to process the request.
When we want to use middlewares for routes, we will do the following example:
1 2 | router <span class="token punctuation">.</span> <span class="token function">GET</span> <span class="token punctuation">(</span> <span class="token string">"/"</span> <span class="token punctuation">,</span> middlewares <span class="token punctuation">.</span> <span class="token function">CheckJwt</span> <span class="token punctuation">(</span> routes <span class="token punctuation">.</span> Hello <span class="token punctuation">)</span> <span class="token punctuation">)</span> |
2. models / Post.go
We will create new Post
models, each user on the system after logging in will have the right to add, edit, delete their own posts. You have the right to view all post
or view the post
you create.
1 2 3 4 5 6 7 8 9 | <span class="token keyword">package</span> models <span class="token keyword">type</span> Post <span class="token keyword">struct</span> <span class="token punctuation">{</span> id <span class="token builtin">string</span> creater <span class="token builtin">string</span> title <span class="token builtin">string</span> <span class="token punctuation">}</span> |
Connecting to the db
Similar to collection users
, we write the connect function to the posts
collection
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <span class="token comment">// database/connect.go</span> <span class="token keyword">func</span> <span class="token function">ConnectPosts</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token operator">*</span> mongo <span class="token punctuation">.</span> Collection <span class="token punctuation">{</span> clientOptions <span class="token operator">:=</span> options <span class="token punctuation">.</span> <span class="token function">Client</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">ApplyURI</span> <span class="token punctuation">(</span> os <span class="token punctuation">.</span> <span class="token function">Getenv</span> <span class="token punctuation">(</span> <span class="token string">"MONGODB_URI"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> client <span class="token punctuation">,</span> err <span class="token operator">:=</span> mongo <span class="token punctuation">.</span> <span class="token function">Connect</span> <span class="token punctuation">(</span> context <span class="token punctuation">.</span> <span class="token function">TODO</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> clientOptions <span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> log <span class="token punctuation">.</span> <span class="token function">Fatal</span> <span class="token punctuation">(</span> err <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">// Check the connection</span> err <span class="token operator">=</span> client <span class="token punctuation">.</span> <span class="token function">Ping</span> <span class="token punctuation">(</span> context <span class="token punctuation">.</span> <span class="token function">TODO</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token boolean">nil</span> <span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> log <span class="token punctuation">.</span> <span class="token function">Fatal</span> <span class="token punctuation">(</span> err <span class="token punctuation">)</span> <span class="token punctuation">}</span> collection <span class="token operator">:=</span> client <span class="token punctuation">.</span> <span class="token function">Database</span> <span class="token punctuation">(</span> <span class="token string">"golang"</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">Collection</span> <span class="token punctuation">(</span> <span class="token string">"posts"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> collection <span class="token punctuation">}</span> |
Step routes with middlewares
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <span class="token comment">// main.go</span> <span class="token keyword">package</span> main <span class="token keyword">import</span> <span class="token punctuation">(</span> <span class="token string">"fmt"</span> <span class="token string">"log"</span> <span class="token string">"net/http"</span> <span class="token string">"github.com/julienschmidt/httprouter"</span> <span class="token string">"github.com/conglt10/web-golang/middlewares"</span> <span class="token string">"github.com/conglt10/web-golang/routes"</span> <span class="token string">"github.com/joho/godotenv"</span> <span class="token punctuation">)</span> <span class="token keyword">func</span> <span class="token function">main</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> err <span class="token operator">:=</span> godotenv <span class="token punctuation">.</span> <span class="token function">Load</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> log <span class="token punctuation">.</span> <span class="token function">Fatalf</span> <span class="token punctuation">(</span> <span class="token string">"Error getting env, %v"</span> <span class="token punctuation">,</span> err <span class="token punctuation">)</span> <span class="token punctuation">}</span> router <span class="token operator">:=</span> httprouter <span class="token punctuation">.</span> <span class="token function">New</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> router <span class="token punctuation">.</span> <span class="token function">POST</span> <span class="token punctuation">(</span> <span class="token string">"/auth/login"</span> <span class="token punctuation">,</span> routes <span class="token punctuation">.</span> Login <span class="token punctuation">)</span> router <span class="token punctuation">.</span> <span class="token function">POST</span> <span class="token punctuation">(</span> <span class="token string">"/auth/register"</span> <span class="token punctuation">,</span> routes <span class="token punctuation">.</span> Register <span class="token punctuation">)</span> router <span class="token punctuation">.</span> <span class="token function">GET</span> <span class="token punctuation">(</span> <span class="token string">"/posts"</span> <span class="token punctuation">,</span> middlewares <span class="token punctuation">.</span> <span class="token function">CheckJwt</span> <span class="token punctuation">(</span> routes <span class="token punctuation">.</span> GetAllPosts <span class="token punctuation">)</span> <span class="token punctuation">)</span> router <span class="token punctuation">.</span> <span class="token function">GET</span> <span class="token punctuation">(</span> <span class="token string">"/me/posts"</span> <span class="token punctuation">,</span> middlewares <span class="token punctuation">.</span> <span class="token function">CheckJwt</span> <span class="token punctuation">(</span> routes <span class="token punctuation">.</span> GetMyPosts <span class="token punctuation">)</span> <span class="token punctuation">)</span> router <span class="token punctuation">.</span> <span class="token function">POST</span> <span class="token punctuation">(</span> <span class="token string">"/posts"</span> <span class="token punctuation">,</span> middlewares <span class="token punctuation">.</span> <span class="token function">CheckJwt</span> <span class="token punctuation">(</span> routes <span class="token punctuation">.</span> CreatePost <span class="token punctuation">)</span> <span class="token punctuation">)</span> router <span class="token punctuation">.</span> <span class="token function">PUT</span> <span class="token punctuation">(</span> <span class="token string">"/posts/:id"</span> <span class="token punctuation">,</span> middlewares <span class="token punctuation">.</span> <span class="token function">CheckJwt</span> <span class="token punctuation">(</span> routes <span class="token punctuation">.</span> EditPost <span class="token punctuation">)</span> <span class="token punctuation">)</span> router <span class="token punctuation">.</span> <span class="token function">DELETE</span> <span class="token punctuation">(</span> <span class="token string">"/posts/:id"</span> <span class="token punctuation">,</span> middlewares <span class="token punctuation">.</span> <span class="token function">CheckJwt</span> <span class="token punctuation">(</span> routes <span class="token punctuation">.</span> DeletePost <span class="token punctuation">)</span> <span class="token punctuation">)</span> fmt <span class="token punctuation">.</span> <span class="token function">Println</span> <span class="token punctuation">(</span> <span class="token string">"Listening to port 8000"</span> <span class="token punctuation">)</span> log <span class="token punctuation">.</span> <span class="token function">Fatal</span> <span class="token punctuation">(</span> http <span class="token punctuation">.</span> <span class="token function">ListenAndServe</span> <span class="token punctuation">(</span> <span class="token string">":8000"</span> <span class="token punctuation">,</span> router <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
3. Processing jsonwebtoken from client
Extract information from jwt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | <span class="token comment">// auth/jwt.go</span> <span class="token keyword">func</span> <span class="token function">Extract</span> <span class="token punctuation">(</span> r <span class="token operator">*</span> http <span class="token punctuation">.</span> Request <span class="token punctuation">)</span> <span class="token builtin">string</span> <span class="token punctuation">{</span> bearerToken <span class="token operator">:=</span> r <span class="token punctuation">.</span> Header <span class="token punctuation">.</span> <span class="token function">Get</span> <span class="token punctuation">(</span> <span class="token string">"Authorization"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> strings <span class="token punctuation">.</span> <span class="token function">Split</span> <span class="token punctuation">(</span> bearerToken <span class="token punctuation">,</span> <span class="token string">" "</span> <span class="token punctuation">)</span> <span class="token punctuation">[</span> <span class="token number">1</span> <span class="token punctuation">]</span> <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">ExtractUsernameFromToken</span> <span class="token punctuation">(</span> r <span class="token operator">*</span> http <span class="token punctuation">.</span> Request <span class="token punctuation">)</span> <span class="token punctuation">(</span> <span class="token builtin">string</span> <span class="token punctuation">,</span> <span class="token builtin">error</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> username <span class="token builtin">string</span> tokenString <span class="token operator">:=</span> <span class="token function">Extract</span> <span class="token punctuation">(</span> r <span class="token punctuation">)</span> token <span class="token punctuation">,</span> err <span class="token operator">:=</span> jwt <span class="token punctuation">.</span> <span class="token function">Parse</span> <span class="token punctuation">(</span> tokenString <span class="token punctuation">,</span> <span class="token keyword">func</span> <span class="token punctuation">(</span> token <span class="token operator">*</span> jwt <span class="token punctuation">.</span> Token <span class="token punctuation">)</span> <span class="token punctuation">(</span> <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token builtin">error</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token boolean">_</span> <span class="token punctuation">,</span> ok <span class="token operator">:=</span> token <span class="token punctuation">.</span> Method <span class="token punctuation">.</span> <span class="token punctuation">(</span> <span class="token operator">*</span> jwt <span class="token punctuation">.</span> SigningMethodHMAC <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token operator">!</span> ok <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">nil</span> <span class="token punctuation">,</span> fmt <span class="token punctuation">.</span> <span class="token function">Errorf</span> <span class="token punctuation">(</span> <span class="token string">"Unexpected signing method: %v"</span> <span class="token punctuation">,</span> token <span class="token punctuation">.</span> Header <span class="token punctuation">[</span> <span class="token string">"alg"</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token function">byte</span> <span class="token punctuation">(</span> os <span class="token punctuation">.</span> <span class="token function">Getenv</span> <span class="token punctuation">(</span> <span class="token string">"SECRET_JWT"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token boolean">nil</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> username <span class="token punctuation">,</span> err <span class="token punctuation">}</span> <span class="token keyword">if</span> claims <span class="token punctuation">,</span> ok <span class="token operator">:=</span> token <span class="token punctuation">.</span> Claims <span class="token punctuation">.</span> <span class="token punctuation">(</span> jwt <span class="token punctuation">.</span> MapClaims <span class="token punctuation">)</span> <span class="token punctuation">;</span> ok <span class="token operator">&&</span> token <span class="token punctuation">.</span> Valid <span class="token punctuation">{</span> username <span class="token operator">=</span> fmt <span class="token punctuation">.</span> <span class="token function">Sprintf</span> <span class="token punctuation">(</span> <span class="token string">"%v"</span> <span class="token punctuation">,</span> claims <span class="token punctuation">[</span> <span class="token string">"username"</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> username <span class="token punctuation">,</span> <span class="token boolean">nil</span> <span class="token punctuation">}</span> |
- The
Extract
function takes the token value in theheader request
, removing redundancy in the header (“Bearer string”). - The
ExtractUsernameFromToken
function extracts the username from the token’s value in order to delegate rights later on to add and deleteroute
.
Verify jwt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | <span class="token comment">// auth/jwt.go</span> <span class="token keyword">func</span> <span class="token function">Verify</span> <span class="token punctuation">(</span> r <span class="token operator">*</span> http <span class="token punctuation">.</span> Request <span class="token punctuation">)</span> <span class="token builtin">error</span> <span class="token punctuation">{</span> tokenString <span class="token operator">:=</span> <span class="token function">Extract</span> <span class="token punctuation">(</span> r <span class="token punctuation">)</span> token <span class="token punctuation">,</span> err <span class="token operator">:=</span> jwt <span class="token punctuation">.</span> <span class="token function">Parse</span> <span class="token punctuation">(</span> tokenString <span class="token punctuation">,</span> <span class="token keyword">func</span> <span class="token punctuation">(</span> token <span class="token operator">*</span> jwt <span class="token punctuation">.</span> Token <span class="token punctuation">)</span> <span class="token punctuation">(</span> <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> <span class="token builtin">error</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">if</span> <span class="token boolean">_</span> <span class="token punctuation">,</span> ok <span class="token operator">:=</span> token <span class="token punctuation">.</span> Method <span class="token punctuation">.</span> <span class="token punctuation">(</span> <span class="token operator">*</span> jwt <span class="token punctuation">.</span> SigningMethodHMAC <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token operator">!</span> ok <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token boolean">nil</span> <span class="token punctuation">,</span> fmt <span class="token punctuation">.</span> <span class="token function">Errorf</span> <span class="token punctuation">(</span> <span class="token string">"Unexpected signing method: %v"</span> <span class="token punctuation">,</span> token <span class="token punctuation">.</span> Header <span class="token punctuation">[</span> <span class="token string">"alg"</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token punctuation">[</span> <span class="token punctuation">]</span> <span class="token function">byte</span> <span class="token punctuation">(</span> os <span class="token punctuation">.</span> <span class="token function">Getenv</span> <span class="token punctuation">(</span> <span class="token string">"SECRET_JWT"</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> <span class="token boolean">nil</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> err <span class="token punctuation">}</span> <span class="token keyword">return</span> <span class="token boolean">nil</span> <span class="token punctuation">}</span> |
The token after being sent by the client will be checked for validity, decrypted with the secret_key
stored in the environment variable. jwt.Parse
function is a bit complicated, if you want to learn more, you can read more at GoDocs .
4. Query posts
Get all posts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | <span class="token comment">// routes/post.go</span> <span class="token keyword">func</span> <span class="token function">GetAllPosts</span> <span class="token punctuation">(</span> w http <span class="token punctuation">.</span> ResponseWriter <span class="token punctuation">,</span> r <span class="token operator">*</span> http <span class="token punctuation">.</span> Request <span class="token punctuation">,</span> <span class="token boolean">_</span> httprouter <span class="token punctuation">.</span> Params <span class="token punctuation">)</span> <span class="token punctuation">{</span> collection <span class="token operator">:=</span> db <span class="token punctuation">.</span> <span class="token function">ConnectPosts</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">var</span> result <span class="token punctuation">[</span> <span class="token punctuation">]</span> bson <span class="token punctuation">.</span> M data <span class="token punctuation">,</span> err <span class="token operator">:=</span> collection <span class="token punctuation">.</span> <span class="token function">Find</span> <span class="token punctuation">(</span> context <span class="token punctuation">.</span> <span class="token function">Background</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> bson <span class="token punctuation">.</span> M <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">500</span> <span class="token punctuation">,</span> <span class="token string">"Internal Server Error"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> <span class="token keyword">defer</span> data <span class="token punctuation">.</span> <span class="token function">Close</span> <span class="token punctuation">(</span> context <span class="token punctuation">.</span> <span class="token function">Background</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">for</span> data <span class="token punctuation">.</span> <span class="token function">Next</span> <span class="token punctuation">(</span> context <span class="token punctuation">.</span> <span class="token function">Background</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> elem bson <span class="token punctuation">.</span> M err <span class="token operator">:=</span> data <span class="token punctuation">.</span> <span class="token function">Decode</span> <span class="token punctuation">(</span> <span class="token operator">&</span> elem <span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">500</span> <span class="token punctuation">,</span> <span class="token string">"Internal Server Error"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> result <span class="token operator">=</span> <span class="token function">append</span> <span class="token punctuation">(</span> result <span class="token punctuation">,</span> elem <span class="token punctuation">)</span> <span class="token punctuation">}</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">200</span> <span class="token punctuation">,</span> result <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
- The first step is to connect to the
posts
collection - Define the
result
variable as an arraybson.M
(bson is a map) - Use the
Find
function of the mongoDB library to query the entire record in theposts
collection - Handle error
- Because the
data
variable stores the return value from theFind
function as a pointer, we need to convert it into abson
form to return the client. (eg:&{ 0xc0003c6840 <nil> 0xc0000d8c40 0xc00037cb40 <nil>}
)Find
prototype of theFind
function:
1 2 3 | <span class="token keyword">func</span> <span class="token punctuation">(</span> coll <span class="token operator">*</span> Collection <span class="token punctuation">)</span> <span class="token function">Find</span> <span class="token punctuation">(</span> ctx context <span class="token punctuation">.</span> Context <span class="token punctuation">,</span> filter <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> opts <span class="token operator">...</span> <span class="token operator">*</span> options <span class="token punctuation">.</span> FindOptions <span class="token punctuation">)</span> <span class="token punctuation">(</span> <span class="token operator">*</span> Cursor <span class="token punctuation">,</span> <span class="token builtin">error</span> <span class="token punctuation">)</span> |
- We use the for function to browse
data
and decode each into a bson form
Get my posts
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | <span class="token comment">// routes/post.go</span> <span class="token keyword">func</span> <span class="token function">GetMyPosts</span> <span class="token punctuation">(</span> w http <span class="token punctuation">.</span> ResponseWriter <span class="token punctuation">,</span> r <span class="token operator">*</span> http <span class="token punctuation">.</span> Request <span class="token punctuation">,</span> <span class="token boolean">_</span> httprouter <span class="token punctuation">.</span> Params <span class="token punctuation">)</span> <span class="token punctuation">{</span> username <span class="token punctuation">,</span> err <span class="token operator">:=</span> jwt <span class="token punctuation">.</span> <span class="token function">ExtractUsernameFromToken</span> <span class="token punctuation">(</span> r <span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">500</span> <span class="token punctuation">,</span> <span class="token string">"Internal Server Error"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> collection <span class="token operator">:=</span> db <span class="token punctuation">.</span> <span class="token function">ConnectPosts</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> <span class="token keyword">var</span> result <span class="token punctuation">[</span> <span class="token punctuation">]</span> bson <span class="token punctuation">.</span> M data <span class="token punctuation">,</span> err <span class="token operator">:=</span> collection <span class="token punctuation">.</span> <span class="token function">Find</span> <span class="token punctuation">(</span> context <span class="token punctuation">.</span> <span class="token function">Background</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> bson <span class="token punctuation">.</span> M <span class="token punctuation">{</span> <span class="token string">"creater"</span> <span class="token punctuation">:</span> username <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token keyword">defer</span> data <span class="token punctuation">.</span> <span class="token function">Close</span> <span class="token punctuation">(</span> context <span class="token punctuation">.</span> <span class="token function">Background</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token keyword">for</span> data <span class="token punctuation">.</span> <span class="token function">Next</span> <span class="token punctuation">(</span> context <span class="token punctuation">.</span> <span class="token function">Background</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> elem bson <span class="token punctuation">.</span> M err <span class="token operator">:=</span> data <span class="token punctuation">.</span> <span class="token function">Decode</span> <span class="token punctuation">(</span> <span class="token operator">&</span> elem <span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">500</span> <span class="token punctuation">,</span> <span class="token string">"Internal Server Error"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> result <span class="token operator">=</span> <span class="token function">append</span> <span class="token punctuation">(</span> result <span class="token punctuation">,</span> elem <span class="token punctuation">)</span> <span class="token punctuation">}</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">200</span> <span class="token punctuation">,</span> result <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
- Similar to the previous section, the
GetMyPosts
functionGetMyPosts
only by extracting the username from the token and addingfilter
provided that the records have thecreater
username extract above.
5. Create post
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | <span class="token comment">// routes/post.go</span> <span class="token keyword">func</span> <span class="token function">CreatePost</span> <span class="token punctuation">(</span> w http <span class="token punctuation">.</span> ResponseWriter <span class="token punctuation">,</span> r <span class="token operator">*</span> http <span class="token punctuation">.</span> Request <span class="token punctuation">,</span> <span class="token boolean">_</span> httprouter <span class="token punctuation">.</span> Params <span class="token punctuation">)</span> <span class="token punctuation">{</span> creater <span class="token punctuation">,</span> err <span class="token operator">:=</span> jwt <span class="token punctuation">.</span> <span class="token function">ExtractUsernameFromToken</span> <span class="token punctuation">(</span> r <span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">500</span> <span class="token punctuation">,</span> <span class="token string">"Internal Server Error"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> title <span class="token operator">:=</span> r <span class="token punctuation">.</span> <span class="token function">PostFormValue</span> <span class="token punctuation">(</span> <span class="token string">"title"</span> <span class="token punctuation">)</span> <span class="token keyword">if</span> govalidator <span class="token punctuation">.</span> <span class="token function">IsNull</span> <span class="token punctuation">(</span> title <span class="token punctuation">)</span> <span class="token punctuation">{</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">400</span> <span class="token punctuation">,</span> <span class="token string">"Data can not empty"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> title <span class="token operator">=</span> models <span class="token punctuation">.</span> <span class="token function">Santize</span> <span class="token punctuation">(</span> title <span class="token punctuation">)</span> uid <span class="token operator">:=</span> uuid <span class="token punctuation">.</span> <span class="token function">NewV4</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> id <span class="token operator">:=</span> fmt <span class="token punctuation">.</span> <span class="token function">Sprintf</span> <span class="token punctuation">(</span> <span class="token string">"%x-%x-%x-%x-%x"</span> <span class="token punctuation">,</span> uid <span class="token punctuation">[</span> <span class="token number">0</span> <span class="token punctuation">:</span> <span class="token number">4</span> <span class="token punctuation">]</span> <span class="token punctuation">,</span> uid <span class="token punctuation">[</span> <span class="token number">4</span> <span class="token punctuation">:</span> <span class="token number">6</span> <span class="token punctuation">]</span> <span class="token punctuation">,</span> uid <span class="token punctuation">[</span> <span class="token number">6</span> <span class="token punctuation">:</span> <span class="token number">8</span> <span class="token punctuation">]</span> <span class="token punctuation">,</span> uid <span class="token punctuation">[</span> <span class="token number">8</span> <span class="token punctuation">:</span> <span class="token number">10</span> <span class="token punctuation">]</span> <span class="token punctuation">,</span> uid <span class="token punctuation">[</span> <span class="token number">10</span> <span class="token punctuation">:</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> collection <span class="token operator">:=</span> db <span class="token punctuation">.</span> <span class="token function">ConnectPosts</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">;</span> newPost <span class="token operator">:=</span> bson <span class="token punctuation">.</span> M <span class="token punctuation">{</span> <span class="token string">"id"</span> <span class="token punctuation">:</span> id <span class="token punctuation">,</span> <span class="token string">"creater"</span> <span class="token punctuation">:</span> creater <span class="token punctuation">,</span> <span class="token string">"title"</span> <span class="token punctuation">:</span> title <span class="token punctuation">}</span> <span class="token boolean">_</span> <span class="token punctuation">,</span> errs <span class="token operator">:=</span> collection <span class="token punctuation">.</span> <span class="token function">InsertOne</span> <span class="token punctuation">(</span> context <span class="token punctuation">.</span> <span class="token function">TODO</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> newPost <span class="token punctuation">)</span> <span class="token keyword">if</span> errs <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">500</span> <span class="token punctuation">,</span> <span class="token string">"Create post has failed"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">201</span> <span class="token punctuation">,</span> <span class="token string">"Create Succesfully"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
- Each
post
will have a uniqueid
(uuidv4 form) - After creating any uid with the function
uuid.NewV4()
, we use thefmt.Sprintf
function to convert the id intoxxxx-xxxx-xxxx-xxx
. - The following we are also quite familiar when connecting db and calling
InsertOne
function to add records to the db.
6. Edit post
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 | <span class="token comment">// routes/post.go</span> <span class="token keyword">func</span> <span class="token function">EditPost</span> <span class="token punctuation">(</span> w http <span class="token punctuation">.</span> ResponseWriter <span class="token punctuation">,</span> r <span class="token operator">*</span> http <span class="token punctuation">.</span> Request <span class="token punctuation">,</span> ps httprouter <span class="token punctuation">.</span> Params <span class="token punctuation">)</span> <span class="token punctuation">{</span> id <span class="token operator">:=</span> ps <span class="token punctuation">.</span> <span class="token function">ByName</span> <span class="token punctuation">(</span> <span class="token string">"id"</span> <span class="token punctuation">)</span> title <span class="token operator">:=</span> r <span class="token punctuation">.</span> <span class="token function">PostFormValue</span> <span class="token punctuation">(</span> <span class="token string">"title"</span> <span class="token punctuation">)</span> username <span class="token punctuation">,</span> err <span class="token operator">:=</span> jwt <span class="token punctuation">.</span> <span class="token function">ExtractUsernameFromToken</span> <span class="token punctuation">(</span> r <span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">500</span> <span class="token punctuation">,</span> <span class="token string">"Internal Server Error"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> <span class="token keyword">if</span> govalidator <span class="token punctuation">.</span> <span class="token function">IsNull</span> <span class="token punctuation">(</span> title <span class="token punctuation">)</span> <span class="token punctuation">{</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">400</span> <span class="token punctuation">,</span> <span class="token string">"Data can not empty"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> collection <span class="token operator">:=</span> db <span class="token punctuation">.</span> <span class="token function">ConnectPosts</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">var</span> result bson <span class="token punctuation">.</span> M errFind <span class="token operator">:=</span> collection <span class="token punctuation">.</span> <span class="token function">FindOne</span> <span class="token punctuation">(</span> context <span class="token punctuation">.</span> <span class="token function">TODO</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> bson <span class="token punctuation">.</span> M <span class="token punctuation">{</span> <span class="token string">"id"</span> <span class="token punctuation">:</span> id <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">Decode</span> <span class="token punctuation">(</span> <span class="token operator">&</span> result <span class="token punctuation">)</span> <span class="token keyword">if</span> errFind <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">404</span> <span class="token punctuation">,</span> <span class="token string">"Post Not Found"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> creater <span class="token operator">:=</span> fmt <span class="token punctuation">.</span> <span class="token function">Sprintf</span> <span class="token punctuation">(</span> <span class="token string">"%v"</span> <span class="token punctuation">,</span> result <span class="token punctuation">[</span> <span class="token string">"creater"</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token keyword">if</span> username <span class="token operator">!=</span> creater <span class="token punctuation">{</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">403</span> <span class="token punctuation">,</span> <span class="token string">"Permission Denied"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> filter <span class="token operator">:=</span> bson <span class="token punctuation">.</span> M <span class="token punctuation">{</span> <span class="token string">"id"</span> <span class="token punctuation">:</span> id <span class="token punctuation">}</span> update <span class="token operator">:=</span> bson <span class="token punctuation">.</span> M <span class="token punctuation">{</span> <span class="token string">"$set"</span> <span class="token punctuation">:</span> bson <span class="token punctuation">.</span> M <span class="token punctuation">{</span> <span class="token string">"title"</span> <span class="token punctuation">:</span> title <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token boolean">_</span> <span class="token punctuation">,</span> errUpdate <span class="token operator">:=</span> collection <span class="token punctuation">.</span> <span class="token function">UpdateOne</span> <span class="token punctuation">(</span> context <span class="token punctuation">.</span> <span class="token function">TODO</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> filter <span class="token punctuation">,</span> update <span class="token punctuation">)</span> <span class="token keyword">if</span> errUpdate <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">500</span> <span class="token punctuation">,</span> <span class="token string">"Edit has failed"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">200</span> <span class="token punctuation">,</span> <span class="token string">"Edit Successfully"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
- The function takes
id
values in params andtitle
in request body. - Validate data
- Connecting to the db
- Look in the db to see if there are any records with the
id
values that match theid
, if not, return a 404. - If so, do we compare the
creater
field in the record with theusername
extract from the token to see if it overlaps? If different, return 403 for the client. - Next we use the
UpdateOne
function to update the value. The function returns 2 values, the first variable is a pointer, we do not need to handle it so leave a_
, just check to see if the update process has an error or not.
1 2 3 | <span class="token keyword">func</span> <span class="token punctuation">(</span> coll <span class="token operator">*</span> Collection <span class="token punctuation">)</span> <span class="token function">UpdateOne</span> <span class="token punctuation">(</span> ctx context <span class="token punctuation">.</span> Context <span class="token punctuation">,</span> filter <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> update <span class="token keyword">interface</span> <span class="token punctuation">{</span> <span class="token punctuation">}</span> <span class="token punctuation">,</span> opts <span class="token operator">...</span> <span class="token operator">*</span> options <span class="token punctuation">.</span> UpdateOptions <span class="token punctuation">)</span> <span class="token punctuation">(</span> <span class="token operator">*</span> UpdateResult <span class="token punctuation">,</span> <span class="token builtin">error</span> <span class="token punctuation">)</span> |
7. Delete post
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <span class="token comment">// routes/post.go</span> <span class="token keyword">func</span> <span class="token function">DeletePost</span> <span class="token punctuation">(</span> w http <span class="token punctuation">.</span> ResponseWriter <span class="token punctuation">,</span> r <span class="token operator">*</span> http <span class="token punctuation">.</span> Request <span class="token punctuation">,</span> ps httprouter <span class="token punctuation">.</span> Params <span class="token punctuation">)</span> <span class="token punctuation">{</span> id <span class="token operator">:=</span> ps <span class="token punctuation">.</span> <span class="token function">ByName</span> <span class="token punctuation">(</span> <span class="token string">"id"</span> <span class="token punctuation">)</span> username <span class="token punctuation">,</span> err <span class="token operator">:=</span> jwt <span class="token punctuation">.</span> <span class="token function">ExtractUsernameFromToken</span> <span class="token punctuation">(</span> r <span class="token punctuation">)</span> collection <span class="token operator">:=</span> db <span class="token punctuation">.</span> <span class="token function">ConnectPosts</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token keyword">if</span> err <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">500</span> <span class="token punctuation">,</span> <span class="token string">"Internal Server Error"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> <span class="token keyword">var</span> result bson <span class="token punctuation">.</span> M errFind <span class="token operator">:=</span> collection <span class="token punctuation">.</span> <span class="token function">FindOne</span> <span class="token punctuation">(</span> context <span class="token punctuation">.</span> <span class="token function">TODO</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> bson <span class="token punctuation">.</span> M <span class="token punctuation">{</span> <span class="token string">"id"</span> <span class="token punctuation">:</span> id <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">Decode</span> <span class="token punctuation">(</span> <span class="token operator">&</span> result <span class="token punctuation">)</span> <span class="token keyword">if</span> errFind <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">404</span> <span class="token punctuation">,</span> <span class="token string">"Post Not Found"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> creater <span class="token operator">:=</span> fmt <span class="token punctuation">.</span> <span class="token function">Sprintf</span> <span class="token punctuation">(</span> <span class="token string">"%v"</span> <span class="token punctuation">,</span> result <span class="token punctuation">[</span> <span class="token string">"creater"</span> <span class="token punctuation">]</span> <span class="token punctuation">)</span> <span class="token keyword">if</span> username <span class="token operator">!=</span> creater <span class="token punctuation">{</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">403</span> <span class="token punctuation">,</span> <span class="token string">"Permission Denied"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> errDelete <span class="token operator">:=</span> collection <span class="token punctuation">.</span> <span class="token function">FindOneAndDelete</span> <span class="token punctuation">(</span> context <span class="token punctuation">.</span> <span class="token function">TODO</span> <span class="token punctuation">(</span> <span class="token punctuation">)</span> <span class="token punctuation">,</span> bson <span class="token punctuation">.</span> M <span class="token punctuation">{</span> <span class="token string">"id"</span> <span class="token punctuation">:</span> id <span class="token punctuation">}</span> <span class="token punctuation">)</span> <span class="token punctuation">.</span> <span class="token function">Decode</span> <span class="token punctuation">(</span> <span class="token operator">&</span> result <span class="token punctuation">)</span> <span class="token keyword">if</span> errDelete <span class="token operator">!=</span> <span class="token boolean">nil</span> <span class="token punctuation">{</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">500</span> <span class="token punctuation">,</span> <span class="token string">"Delete has failed"</span> <span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> res <span class="token punctuation">.</span> <span class="token function">JSON</span> <span class="token punctuation">(</span> w <span class="token punctuation">,</span> <span class="token number">200</span> <span class="token punctuation">,</span> <span class="token string">"Delete Successfully"</span> <span class="token punctuation">)</span> <span class="token punctuation">}</span> |
- The
DeletePost
function is similar to the edit function above, except that it uses theFindOneAndDelete
function
References
https://godoc.org/go.mongodb.org/mongo-driver/mongo https://godoc.org/github.com/julienschmidt
https://www.alexedwards.net/blog/a-recap-of-request-handling https://www.alexedwards.net/blog/making-and-using-middleware