DEV Community

Humphery
Humphery

Posted on

Building a String Analyzer Service: From Concept to Deployment

By Humphery Otuoniyo

I built a RESTful API service designed to analyze strings and store their computed properties. The project offered a hands-on experience in backend development, from schema design to deployment on Railway, and highlighted the importance of robust data validation and flexible querying.

Project Overview

The service analyzes any submitted string and computes several properties:

  • Length: Number of characters in the string
  • Is Palindrome: Boolean indicating whether the string reads the same forwards and backwards (case-insensitive)
  • Unique Characters: Count of distinct characters
  • Word Count: Number of words separated by whitespace
  • SHA-256 Hash: Unique identifier for the string
  • Character Frequency Map: A dictionary mapping each character to its occurrence count

This allowed the service to not only store strings efficiently but also provide analytical insights for further queries.

API Endpoints

The service exposes five key endpoints, each serving a specific purpose:

1. Create/Analyze String

POST /strings

Users can submit a string in JSON format, and the service computes its properties and stores it:

{
  "value": "string to analyze"
}
Enter fullscreen mode Exit fullscreen mode

Successful responses include the computed properties and the SHA-256 hash. The service handles conflicts and invalid input gracefully, returning appropriate status codes such as 409 Conflict if the string already exists, 400 Bad Request for missing fields, or 422 Unprocessable Entity if the value type is incorrect.

2. Get Specific String

GET /strings/{string_value}

This endpoint retrieves a single string and its properties. If the string does not exist, a 404 Not Found is returned.

3. Get All Strings with Filtering

GET /strings?is_palindrome=true&min_length=5&max_length=20&word_count=2&contains_character=a

The service allows powerful query filtering:

  • is_palindrome: boolean
  • min_length and max_length: integers
  • word_count: exact number of words
  • contains_character: a single character

Responses include all matching strings, the total count, and a record of the filters applied. Invalid query parameters are rejected with 400 Bad Request.

4. Natural Language Filtering

GET /strings/filter-by-natural-language?query=all%20single%20word%20palindromic%20strings

One of the most interesting features is the ability to parse natural language queries. The service interprets queries like:

  • "all single word palindromic strings"word_count=1, is_palindrome=true
  • "strings longer than 10 characters"min_length=11
  • "palindromic strings that contain the first vowel"is_palindrome=true, contains_character=a

If the query cannot be parsed or results in conflicting filters, the API returns 400 Bad Request or 422 Unprocessable Entity.

5. Delete String

DELETE /strings/{string_value}

Users can remove a specific string from the system. If the string does not exist, a 404 Not Found is returned. Importantly, the endpoint ensures safety by not deleting all data if the parameter is missing.

Development Highlights

Data Validation and Type Safety

Handling numeric filters such as min_length, max_length, and word_count required strict integer validation. Using Number combined with Number.isInteger() ensured that the API rejected decimals, negative numbers, and non-numeric input while accepting valid integers.

Palindrome Detection and Character Analysis

For palindromes, the service ignores case and spaces, providing an accurate boolean flag. Character frequency maps and unique character counts are computed efficiently using simple iteration over the string.

Hashing for Unique Identification

SHA-256 hashing provides a reliable way to identify strings uniquely, which is especially useful for avoiding duplicates and quickly locating records.

Deployment Considerations

Deploying on Railway introduced the common challenge of environment variable handling. Railway sometimes wraps values in quotes, which would break the MongoDB connection. This was handled by sanitizing the MONGO_URI in the connection logic:

let mongoUri = process.env.MONGO_URI;
if (mongoUri.startsWith('"') && mongoUri.endsWith('"')) {
    mongoUri = mongoUri.slice(1, -1);
}
Enter fullscreen mode Exit fullscreen mode

This approach ensured a smooth connection to MongoDB Atlas without manual intervention.

Lessons Learned

Building the String Analyzer Service reinforced several best practices:

  • Always validate and sanitize input, especially for numeric and string-based filters
  • Use unique identifiers like hashes to prevent duplicate entries
  • Implement comprehensive error handling to guide API users
  • Consider deployment quirks like environment variable formatting early in development

Conclusion

This project demonstrates how a well-structured backend service can provide both analytical functionality and robust, user-friendly endpoints. The combination of computed string properties, filtering capabilities, and natural language interpretation makes it a versatile tool for string analysis. Deploying to Railway and ensuring smooth operation in a cloud environment highlighted real-world considerations that are crucial for any backend engineer.

Github code

Top comments (0)