castamir / currency-convertor-app

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

CurrencyConvertorApp

This workspace has been generated by Nx, a Smart, fast and extensible build system.

Installation

step 1

yarn install

step 2

Copy & rename .env.example file to just .env in apps/server folder. You need to enter ApiLayer APP ID. While it is explicitly said in the assignment to avoid any additional installation step, storing credentials into code is simply not an option for me. I can provide you my APP ID key via email or you can use your own (ideal case).

Development client

Run nx serve client for a dev client. Navigate to http://localhost:4200/. The app will automatically reload if you change any of the source files.

Development server

Run nx serve server for a dev server. Navigate to http://localhost:3333/. The app will automatically reload if you change any of the source files.

Implementation notes

  • The entire monorepo skeleton was generated by Nx.
  • I spend ~10-12 hours on this solution. It's quite a lot considering how much can Nx generate, but I had limited time on this last week. Also, I've never done any nodejs backend, so I had to learn some basics. I also decided to try out a new library for forms: react-hook-form, as an alternative to Formik. I also tested Open exchange service until I realized that this service requires paid access to finish this homework, so I had to switch to ApiLayer.
  • I did not use Cypress for testing even tho Nx generated a boiler plate to do so. The reason is simple - while I can downgrade Cypress E2E tests to unit/integration tests by mocking http layer, I can do the same thing much faster and much easier using RTL and jest. E2E tests requires data seeding and environment restoration and I did not feel confident to start this until I have the rest completed.
  • On FE side, there is a lot of code that a developer does not have to write (or even should not wite) on his own, such code should be generated instead. As an example, I created __generated__/ folder with some content generated from API (API calls, types and even an example react hook). To demonstrate how I usually work with custom hooks, I implemented 2 of them and added tests using testing-library/react. For simple UI I decided to go with Material UI, but I did not want to spend much time to actually design UI (I'm not UX designer to make it really pretty).
  • Stats UX is not ideal as I did not want to refetch stats with every conversion request. The reason is simple - this backend is a public API and there might be tens or even thousands other users, so there could be quite large data bump once a new dataset is received from a server. Instead, I would recommend a real-time updates using websockets or PubNub or similar technologies. On the other hand, I implemented at least some user friendly feature to manually refresh data (user does not need to refresh the page to get new stats, a simple button click should do the trick). The point is to make it clear that converting currencies and refreshing stats are 2 different user actions.
  • On BE, I decided to organize routes by sections (currencies and stats). I'm aware that naming here is not ideal as there is plenty of other options how to structure routes. I decided to go with GET /api/currencies, POST /api/currencies/convert and GET /api/stats. Stats do not seems to be related only to currency conversions, so I kept them separated. I also wanted to be open to dynamic list of supported currencies, but I started with 4 currencies for sake of simplicity. Finally a POST action to convert currencies. Here I decided to return query args in the response and I also wanted to keep flat structure of this response (but I can image that query args could be wrapped into query attribute or something like that).
  • I wasn't sure how event's and logging is done properly in express JS, but I found some way that I feel confortable with. I explicitly add res.on("finish") to the convert endpoint and let a different service handle stats/logging itself once the response is sent.
  • Stats logging is done via file stored in the root of this project. file location is something that will probbaly need to change depending on how this application will be deployed. Ideally, I would prefer to use a database as it provides tools like atomicity and transactions, but I stayed with a simple solution for now. I considered even SQLITE, but I think that such solution would bring more problems than provide solutions.
  • I did not implement CI in this project, but it can be done. Nx has quite a good support for this.
  • While there is always something that can be improved or simply done better, I wanted to provide a solution in a reasonable time and in a decent quality.

About


Languages

Language:TypeScript 96.4%Language:JavaScript 2.3%Language:HTML 1.1%Language:Shell 0.3%