Giter Club home page Giter Club logo

userservice's Introduction

User Service

Demo user service. The service serves both REST API server and gRPC server.

  • HTTP API is served in the port :8080
  • gRPC is served in the port 50051

How to start the application

The application can be launched in two different ways:

Docker

$ docker-compose up

Run application natively

$ docker run -d -p 27017:27017 mongo:latest
$ go mod download
$ DB_URI=mongodb://localhost:27017/users go run main.go

Available gRPC methods

  • Check() and Watch() – for healthcheck according to the grpc google.golang.org/grpc/health/grpc_health_v1 healthcheck standard
  • CreateUser() – create a new user
  • GetUsers() - fetch all users, filterable
  • GetUserById() – fetch a specific user by ID
  • UpdateUser() – update a specific user (identified by ID)
  • DeleteUser() – delete a specific user (identified by ID)

Available endpoints REST API

  • GET /healthz – a health check endpoint
  • POST /v1/users – create a new user
  • GET /v1/users – get all users (with filters, the filter parameters are case-sensitive)
  • GET /v1/users/:userId – get a user by ID
  • PUT /v1/users/:userId - update a user
  • DELETE /v1/users/:userId - delete a user

Validations for POST /v1/users and PUT /v1/users

A very basic field validation exists for POST and PUT operations The following are the required fields while creating the user

  • first_name
  • last_name
  • email
  • password

Allowed filter parameters for GET /v1/users

The filter parameters are case sensitive

  • first_name
  • last_name
  • nickname
  • email
  • offset – pagination parameters
  • limit – maximum number of items per request

Run the unit tests

$ go test ./...

Integration tests

  • Integration tests have been skipped for this demo as suggested

Trying out the Endpoints

  • You can import the Postman collection - userservice.postman_collection.json and try out the endpoints

Assumptions Made

  • Assumed that the fields first_name, last_name, email, and password are required
  • Assuming that the other services that are interested in the changes in the user entities are internal, message broker system like Kafka/RabbitMQ/SQS can be used to notify them
  • For this demo implementation, boilerplace code for kafka like message broker has been skipped, instead the message broker is emulated with a dummy Publish() function
  • Also skipped designing the OpenAPI/Swagger documentation
  • Password field is hashed before storing (during creation and updating)
  • Password is not included in the response to GET requests

Possible Extension/Improvements

Basic Improvements

  • Validations:
    • Payload field validations
    • Verfication if a user already exists - eg: a user with duplicate email should not be allowed
  • If there are 3rd party external services that should be notified, then notifying them via webhook would be sensible. For that, we would also need a subscription management system, where the interested parties/clients can subscribe to the events that we expose. In the subscription, the subscriber should provide their REST API uri (along with credentials) that should be invoked when an event occurs.
  • Make use of a better logger framework like - zerolog
  • Page numbering system can be improved (using cursor instead of pagesize and number)

Production Deployment

  • It is better to use even lean docker image for production deployment / image - instead of the golang-alpine image, we can just use the alpine image to run the already built application
  • The default parameters used in the application like PORT number, TIMEOUT, DB_URI etc should be passed as environment variable to the service
  • Make use of migration image and script to prepare the database schema.
  • Also make use DB indexes. It would be smart to create indexes on the fields that are allowed the query parameters (filterables).
  • Proper API documentation - like OpenAPI/Swagger with payload schema for each of the endpoints should be considered
  • Extensive integration tests with different flows and end-to-end scenarios should be executed on deployment

Scaling

  • There can be several ways to scale the service depending on the usage.
  • The straight forward approach would be horizontal scaling – simply deploy more instances (increase the maximum number of pods in kubernetes)
  • Although, more refined approach would be to determine which operations are more in demand
  • If the READ operations (GET /v1/users and GET /v1/users/:userId) are more frequent, then it might make sense to implement caching layers
  • In case of too frequent WRITE operations – one approach would be to use the pure event driven architecure with the CQRS pattern, where the incoming requests (write operations) are only written to kafka / of similarly high performant message broker, and the response would be 202 Accepted instead of 201 Created. Updating of the database takes place asynchronously after the message is consumed from kafka. This approach also enables the service to independently scale the READ componnet and WRITE component.

The folder structure:

  • apiusers – the API layer
  • db – the Storage(Database) layer
  • events – simply holds the event structs for any changes on user entity (create, update, delete)
  • grpc – the gRPC layer
  • messagebroker – a dummy message broker
  • mocks – for unit/mock tests
  • services – service layer implementations
  • usererrors - custom errors for the service
  • utils – common utilities like: hashing a password

userservice's People

Contributors

sushilman avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.