Deleting a non-existing identity in DynamoDB Golang - go

I am having a golang project where I am using dynamoDB as my backend database. I wanted to return the error when we are trying to Delete a non-existing entity. But the DynamoDB.DeleteItem does not return an error on that thing. Please help me with that.

You can actually do it using the response you will get from DeleteItem method in dynamoDB.
Ex:
resp, err := dynamoDB.DeleteItem(input)
if resp.ConsumedCapacity != nil {
\\entity not found error
}

Actually, the first struct returned by the DeleteItem function is a DeleteItemOutput
There's a comment that addresses how this object would be present
This map appears in the response only if ReturnValues was specified as ALL_OLD in the request.
You can adjust your logic accordingly and it might solve your problem

Related

Problem redirecting and using gorilla sessions in golang

Hello everyone I ask for help because I have a problem when I want to redirect and save sessions with gorilla sessions, I have a url which validates an http post request, and this is the code:
if err != nil {
// here i create a session using gorilla sessions with a function that i created
flash := NewFlashSession("errors", c)
// and here i set the error with a function that i also created
flash.Set("general", "Error :(")
// and i guess this is where the error starts
flash.Save()
http.Redirect(r.Writer, r.Request, "url", statusCode)
}
Actually I have a bit more complex model to explain it all in this question, but in summary what the "flash.Save()" function does is use the ".Save()" method of gorilla sessions, which receives an object "*http.Request" and "http.ResponseWriter".
And the variable "err" is an error caused by some error in validation, but when an error occurs and I want to redirect, I get the following error:
http: superfluous answer. WriteHeader call
And after doing some research, I realized that this was the cause of the problem, but. How can I save a session using Gorilla Sessions and then do a redirect? Or is there any other way to do it?
I hope you have understood me, if I do not explain myself well or if you need more information, I will try to show more of the code, I did not do it because it seems to me that the error is when I save the session and then do the redirection, and it seems to me needless to show the rest of the code. Thank you in advance :D.
I tried your code, and as they put in the comments, when adding a return there is no longer an error:
if err != nil {
// here i create a session using gorilla sessions with a function that i created
flash := NewFlashSession("errors", c)
// and here i set the error with a function that i also created
flash.Set("general", "Error :(")
// and i guess this is where the error starts
flash.Save()
http.Redirect(r.Writer, r.Request, "url", statusCode)
return;
}

show static image based on users in golang gin

I'm using the Gin framework. I have a database that contains some course info. Users can register in the courses and access the contents. The contents are image, video, and audio.
I store the relative location of these contents in my database like this:
Content\Courses\CourseOne\Unit_1\image\1.jpg
and change it to the actual location in gin:
route := gin.Default()
route.Static("/Content","./Media")
Everything works fine, but I am looking for a way to authenticate users before accessing the contents. In the above-mentioned way, all users can access any data by changing the desired pattern's address. But I want if the user is registered in the course, be able to access data, otherwise, get a 404 error.
how can I do that?
Edit
since it was asked to explain the implementation of authentication:
I used JWT for authentication. so each user has a HashID.
I have a table called UserCourses and the user info would be inserted after purchasing a course.
this is my course route:
route.GET("api/v1/courses", handler.GetCourses)
and my handler:
func GetCourses(context *gin.Context) {
hashID, status, err := repository.GetToken(context)
if err != nil {
context.IndentedJSON(status, err)
return
}
courses := make([]model.CourseAPI, 0)
userInfo := model.Users{HashID: hashID}
err = repository.DatabaseInstance.GetCourses(&courses, &userInfo)
if err != nil {
context.IndentedJSON(http.StatusServiceUnavailable, err)
return
}
context.IndentedJSON(http.StatusOK, gin.H{"courses": courses})
}
The JWT token is passed by the client in the header. so I get the token and validate it. The token contains the user HashID and I check for that HashID in the UserCourses table. besides the course info, there is a variable called isRegistered.if the HashID was registered for any course in UserCourses table,the isRegistered become true for that course otherwise false.
You can create group route and apply authentication middleware through it
r = gin.Default()
// public routes
r.GET("public", publicHandler)
// routes group
auth = r.Group("/")
// authentication middleware within group
auth.Use(AuthMiddleware())
// route before which auth middleware will be run
auth.Static("/Content","./Media")

Retain original URL in redirect error message

I'm trying to determine if a webpage exists on a particular website, by sending a GET request to the specific page. However, if the webpage doesn't exist, the website redirects the request to the home page.
To overcome this, I've implemented the redirection prevention, as stated here, which looks something like
func RedirectCheck(req *http.Request, via []*http.Request) error {
if req.Response.StatusCode == 200 {
// no redirection occured
return nil
}
// return error code
return errors.New("webpage doesn't exist")
}
The redirection prevention works fine, but, if I made a get request to https://someurl.com/page1, the error message that I recieve is
Get "https://someurl.com": webpage doesn't exist
How do I configure the error message so that the original URL is retained in the error message?
The error message should then be
Get "https://someurl.com/page1": webpage doesn't exist
The Client.CheckRedirect documentation says:
As a special case, if CheckRedirect returns ErrUseLastResponse,then the most recent response is returned with its body unclosed, along with a nil error.
Fix by returning ErrUseLastResponse from the function:
func RedirectCheck(req *http.Request, via []*http.Request) error {
return http.ErroUseLastResponse
}

Go gin response middleware

I need to manipulate response data in a middleware function. Assume I have product handlers and customer handlers. Product handler returns a list of products and customer returns a list of customers. In the middleware function, I want to convert these responses into ApiResponse struct.
type ApiResponse struct{
Data interface{}
Status ApiStatus{}
}
func someMiddleware(c *gin.Context){
//before handlers
c.Next()
//I need to access response and manipulate it
// apiResponse := ApiResponse{}
// apiResponse.Data = returnedData
// apiResponse.Status = ApiStatus{}
}
I don't want to fill ApiResponse in all handlerFunctions.
Probably a bit too late, but anyway.
The easiest way is usually to use Get and Set methods of gin.Context to pass data between your middleware and your handlers.
But if you really need to intercept responses, see my answer about logging response in gin. The only difference is what you do with intercepted response, but everything said there about intercepting it stays true.

API Discovering its own URL Golang

I've created an API in Go that can search or directly access an Element via ElasticSearch, which then adds some data to the JSON payload, and returns that to the user. When searching I'm returning a list of Elements, and I'd like to be able to give a direct URL to the specific Element should the user wish to get more information.
However I can't ascertain how the application is supposed to figure out its own URL. In the event that it can't, what would be a reasonable alternative for the URL itself?
Using net/http package and gorilla/mux for net based things.
You can "reverse" a gorilla/mux url by looking up the route by name, and generating the url with Route.URL
You will want to name your route, so that you can easily look it up via Router.Get.
r := mux.NewRouter()
r.HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
Name("article")
And once you have the route, you can build a url by passing the parameters to URL
url, err := r.Get("article").URL("category", "technology", "id", "42")
// "/articles/technology/42"
Note that if you want the host to be inserted automatically, it will need to be defined on your route:
r := mux.NewRouter()
r.Host("{subdomain}.domain.com").
HandleFunc("/articles/{category}/{id:[0-9]+}", ArticleHandler).
Name("article")
// url.String() will be "http://news.domain.com/articles/technology/42"
url, err := r.Get("article").URL("subdomain", "news",
"category", "technology",
"id", "42")

Resources