Skip to content
Advertisement

What is the best way to pass in authenticated user information to a sql query?

My web application uses a table users, posts and votes, where a user can create a post and the votes table contains single votes made by some user on some post (think of Hackernews or Reddit).

When using SQL to query a post from posts, I am creating a a variable in SQL called votable, that denotes a) if the post is made by the user currently logged in (denoted by a 2), already voted on by logged in user (denoted by 0), or not yet voted on (denoted by 1).

The variable creation looks like this and passes in the id of the logged in user (or value 0 if not logged in):

IF(posts.user_id = ?, 2, NOT EXISTS (SELECT * FROM votes WHERE user_id = ? AND post_id = posts.id)) AS votable

The signature of the function to get a post in my sql package is:

func (m *PostModel) GetByID(loggedInUserID, postID int) (*models.Post, error) 

But is this a case where using context makes sense as in my handlers the context contains information on the logged in user? Or is it fine this way, where the handler just passes in the loggedInUserID to the function directly and my sql package is more isolated from the details of implementing the context?

Advertisement

Answer

Hiding essential data in a context.Context is not a good idea. It takes away the explicitness, readability and it is hard to know if the data actually exists in the context.

You can however add a context.Context to the function to be able set timeouts or cancel it if for some reason you don’t need the result any more (e.g. the http request was cancelled / timed out).

func (m *PostModel) GetByID(ctx context.Context, loggedInUserID, postID int) (*models.Post, error)

Then pass the context in to query execution.

User contributions licensed under: CC BY-SA
6 People found this is helpful
Advertisement