Demo: https://mymycocktails.netlify.app/
Built with React, Redux, Material-ui, Express, MongoDB.
Put one kind of liquor you have into the cocktail shaker. This app will show you a cocktail recipe.
You can search by name, liquor type or both.
For signed user, you can add recipes to your bar.
I enjoy and appreciate good drinks. However, my girlfriend and I found that searching for an easy cocktail recipe takes time.
Often recipes are filled with useless information. I scroll down and once reach the ingredient section, I find that I don’t have all the ingredients and need to repeat them. I just didn’t like to repeat the process.
Create an app that can provide relatively easy recipes with simple search functions. Even if the user does not have all the ingredients, this app should be able to suggest other options.
- Brainstorm app features.
- Choose tools.
- Browse other cocktail recipe apps. Add or remove features.
- Brainstorm design.
- Start coding!
- Build basic structure (to test backend).
- Build API and make sample data in mongodb.
- Build front-end. Test if data retrieves are working fine.
- Start styling and deploy.
- Small touch-ups.
Problems | Solution / Learning outcome |
---|---|
No idea how to implement authentication. | Researched how to implement Google auth and JSON web token. During this process, I found that I have two ways of authentication and authorization of a user. 1. Session Cookies. 2. JWT Process for Cookies: When the user signs in, the server will create session data and store it in its memory. After the server creates a session cookie in its memory, it will be sent to the user in ‘Set-Cookie: session ID’ form. This will be contained in every request header that the user makes and the server will use this to verify the user. Process for JWT: When the user signs in, unlike using cookies, the server does not create or store any information. Instead, the server will verify first if the user can successfully log in. After the user is authenticated, the server creates JSON Web Token, which is used for authorization. JWT will be stored in the client's localStorage or session storage or cookie and it will be used on every request either in the header or body. Once the server receives the JWT, it de-codes to validate the user. Advantages of JWT Saves the server memory since it does not need to record, only needs to issue a token. Caution! Do not include sensitive information in JWT. Although it says ‘encrypted’, it is not. JWT contains 3 parts (header, payload, signature). I used jsonwebtoken npm package, the order is (payload, secretOrPrivateKey, [options, callback]). Actually code is jwt.sign( {email: existingUser.email, id: existingUser._id}, process.env.JWT_SECRET,
) |
Security concerns came along with authentication. | Learned XSS (Cross-Site Scripting) and CSRF (Cross-Site Request Forgery). There are many articles about XSS and CSRF and how to prevent attacks. I will need to read again and practice. Implemented expiration time in JWT. Using expiration can increase the chance of compromised tokens becoming useless. |
Redux only supports synchronous and has some rules when updating a store. | Researched and wrote a short article about why Redux needed a middleware like redux-thunk. https://dev.to/jaebungs/why-redux-thunk- 1dka |
Both server and client files are in the same folder. This caused many problems during deployment due to my lack of experience. | After long hours of searching and fixing, back-end is deployed on Heroku and front-end is deployed on Netlify. Netlify is connected to the Github repository for easy and fast CD. |
Too many manual testing on API calls, Redux state changes, component rendering, filter and search functions. | Yes I heard benefits of testing a lot, but I haven't felt any necessity before. However, although the app is small, I had to do lots of manual checking for API calls and page renderings, etc. Now I can tell why testing is important. The next project will use testing tools like Jest and Enzyme. |
Rendering SVG files. Things to consider when choosing image types. |
It was my first time using an SVG format image on an app. There are some options for using SVG files. First, use it with . Second, use it as a component (inline SVG). Using SVG as a component is better because we can control style and even animate SVG files. This app is not CRA, thus, SVGR library was required and used in webpack. On top of that, I learned differences between image types.
PNG quality is better, but differences are hard to notice with eyes. Thus, JPEG wins over PNG. |
Production site renders too slow because of the bundle size. | Mind-blowing moment. React lazy and Suspense! Code splitting was very easy with these two APIs. Bundle size got reduced from 463KB to 246KB just by doing Route-based code splitting. This seems simpler than webpack code splitting. |
-
Love Redux hooks! (useSelector, useDispatch). These two hooks simply replaced mapStateToProps and Connect. As a result, the code got simpler, shorter and easy to track.
-
Proficient using React hooks.
-
This project made me dive deep into how React rendering works. https://blog.isquaredsoftware.com/2020/05/blogged-answers-a-mostly-complete-guide-to-react-rendering-behavior This article by Mark was really helpful.
-
Normalize data, embed or reference
-
Material-UI
-
Learned Lighthouse.
-
Browse other cocktail recipe apps. Add or remove features.
- To differentiate from other apps already on the web/store, I had to know their design and features.
-
Brainstorm design. Clean and minimalistic design can allow users to focus on the contents. Same layout for Library and My bar page.
-
Start coding! Build basic structure (to test backend). Build API and make sample data in mongodb. Build front-end. Test if data retrieves are working fine. Start styling and deploy. Small touch-ups.