Getting filler text from the Lipsum.com REST API

I had the need to generate some random filler text for a bunch of records today, and I wanted to use the Lorem Ipsum latin text. Normally, I use the great website Lipsum.com and fill out the form and hit submit. Then, I copy the text provided into my destination.
(This project (reusable .NET class library and sample app) can be found on GitHub at https://github.com/cerkit/LoremIpsum/)
However, I needed to automate this process, so I did a little poking around. It turns out that the lipsum.com website exposes a json feed that can be altered based on your needs.
Note: Using the Lipsum website in this manner is placing stress on their web server. As such, I highly suggest using the donate link provided within the data set that is returned to provide them with a little money to support your efforts.
I wrote my code in such a way as to limit the call rate to one call per second. It took a lot longer to insert my records than I wanted, but I felt sure I wasn't putting unneeded strain on their servers.
The main endpoint for accessing the default data set is: http://lipsum.com/feed/json.
This will give you the following results:
{
feed: {
lipsum: "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Cras tristique massa eu porttitor aliquam. Vivamus sodales sit amet nulla nec volutpat. Sed accumsan iaculis turpis, maximus sagittis ipsum tincidunt et. Cras ac velit eu quam cursus lobortis sit amet vitae quam. Donec nec odio at ligula porttitor viverra nec eu est. Praesent non quam ipsum. Curabitur vitae scelerisque augue. In sed elementum velit. Donec lacinia ut leo a porttitor. Phasellus nec risus placerat, pulvinar ante euismod, tempus lacus. Nam turpis velit, accumsan eget placerat porttitor, hendrerit vitae tortor. Vivamus posuere leo elit, at pretium justo imperdiet id. Duis finibus ante vel mollis rhoncus. Donec sollicitudin sed tortor vulputate bibendum. Aenean tincidunt nisi sed libero sollicitudin, in interdum erat efficitur. Phasellus porttitor faucibus risus non consectetur. Nam a sollicitudin erat, ut lacinia leo. Praesent convallis odio orci, a iaculis lacus viverra non. Maecenas consequat, risus nec egestas consectetur, tellus tellus condimentum mi, in suscipit metus sem quis velit. In a lorem semper, tincidunt mauris a, blandit erat. Aliquam non auctor tortor, et mattis nibh. Aenean at magna at diam commodo feugiat sit amet ut erat. Nunc hendrerit tempus imperdiet. Phasellus varius id justo non vestibulum. Ut quis mollis mauris. Aliquam egestas arcu non erat congue, id ornare elit molestie. Pellentesque rutrum nunc sed arcu semper mollis. Proin malesuada tristique quam quis luctus. Nunc dignissim, orci vitae rhoncus porta, orci enim accumsan urna, ut egestas metus lectus id turpis. Sed in nisi ligula. Etiam sodales est arcu, vitae dignissim metus blandit id. Aenean leo velit, blandit sit amet ex vel, vestibulum ornare ipsum. Donec rutrum euismod velit, ac fringilla leo iaculis ornare. Duis a eros id odio aliquet vestibulum quis vel est. Sed ultricies ac sapien sed tincidunt. Integer bibendum turpis at nisl venenatis facilisis. Morbi sodales dignissim lectus, non sagittis purus cursus dignissim. Phasellus aliquam elementum venenatis. Nunc sed pharetra purus, id blandit velit. In sed massa consequat, posuere nulla non, rhoncus orci. Maecenas a consequat lorem. Morbi sit amet quam felis. Sed at posuere metus. Morbi vestibulum nisl id massa euismod malesuada. Aenean accumsan, elit eu finibus pellentesque, elit metus faucibus tellus, non interdum lacus massa ut velit. Suspendisse fermentum elit sed ipsum luctus consequat. Suspendisse potenti. Aenean sagittis lorem augue, quis condimentum velit facilisis eu. Vivamus posuere ante sed porta fringilla. Morbi pharetra lorem id urna iaculis cursus. Pellentesque at arcu vel lacus euismod accumsan. Sed pretium turpis odio, id tincidunt nisi blandit nec. Suspendisse non ornare massa. Proin facilisis porta dolor nec vestibulum. Aenean accumsan pulvinar magna, in auctor odio tempor eget. Morbi in rutrum quam. Fusce quis ipsum augue. Duis et ligula ut tellus sollicitudin rutrum sit amet eget nisi. Duis id est sit amet orci venenatis consectetur et eget ipsum.",
generated: "Generated 5 paragraphs, 454 words, 3017 bytes of Lorem Ipsum",
donatelink: "http://www.lipsum.com/donate",
creditlink: "http://www.lipsum.com/",
creditname: "James Wilson"
}
}
I decided to take a look at the source code for the home page and get an idea of the form names that are used to set the options for the feed.
I found the following query string arguments
what
: valid values =paras
,words
,bytes
, andlists
amount
: the amount of the chosen type to return (the minimum value is5
for words)start
:yes
orno
depending on whether or not you want to start with "Lorem Ipsum". If set tono
, you'll get a random return value.
So, I wrote my program to loop through the days in the current year and insert a record for each day, adding the random "lipsum" text to the record.
Here's a quick C# program that will use the Newtonsoft.Json library to deserialize the lipsum result into an object that you can use in your code.
This assumes that you're using Visual Studio (community or professional edition).
First, visit the following url: http://lipsum.com/feed/json?amount=5&start=no&what=words
Now, view the source of the results and copy them to your clipboard. Start a new project in Visual Studio (if you don't already have one open) and then create a new class. Name the file LoremIpsum.cs.
It will generate the following code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace LoremIpsum
{
class LoremIpsum
{
}
}
Delete the class LoremIpsum
that it generated (but keep the rest of the file).
Click inside the namespace and choose Edit->Paste Special->Paste JSON as Classes
from the main menu.
This will insert classes that are compatible with the lipsum data. Rename the Rootobject
class to LoremIpsum
. Your code should look like the following (LoremIpsum.cs):
namespace LoremIpsum
{
public class LoremIpsum
{
public Feed feed { get; set; }
}
public class Feed
{
public string lipsum { get; set; }
public string generated { get; set; }
public string donatelink { get; set; }
public string creditlink { get; set; }
public string creditname { get; set; }
}
}
Now, we will need to fetch the data and deserialize it into an object we can use.
Before we continue, make sure you have a reference to the Newtonsoft.Json library. You can use nuGet to install it easily.
First, we'll define an enum to represent the result types:
public enum LipsumType
{
[Description("words")]
Words,
[Description("paras")]
Paragraphs,
[Description("bytes")]
Bytes,
[Description("lists")]
Lists
}
Notice that I used the System.ComponentModel.Description
attribute on each of the enum values to represent the values that need to get sent to the api. This will come in handy later.
Here is a generic extension method on enums that will return the description (this works on any enum containing values decorated with the System.ComponentModel.DescriptionAttribute
class):
public static string GetDescription(this T e) where T : IConvertible
{
Array values = System.Enum.GetValues(e.GetType());
string description = null;
foreach (int val in values)
{
if (val == e.ToInt32(CultureInfo.InvariantCulture))
{
var type = e.GetType();
var memInfo = type.GetMember(Enum.GetName(type, val));
var attributes = memInfo[0].GetCustomAttributes(typeof(DescriptionAttribute), false);
description = ((DescriptionAttribute)attributes[0]).Description;
}
}
return description;
}
Now, let's move on to the actual web call:
public static readonly string LIPSUM_JSON_URL = "http://lipsum.com/feed/json?amount={0}&start={1}&what={2}";
public static LoremIpsum GetNewLipsum(LipsumType lipsumType, int amount, bool startWithLoremIpsum = true, ICredentials proxyCredentials = null)
{
string requestUrl = string.Format(LIPSUM_JSON_URL, amount, startWithLoremIpsum ? "yes" : "no", lipsumType.GetDescription());
HttpWebRequest request = WebRequest.Create(requestUrl) as HttpWebRequest;
if (proxyCredentials != null)
{
request.Proxy.Credentials = proxyCredentials;
}
using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
{
if (response.StatusCode != HttpStatusCode.OK)
throw new Exception(String.Format(
"Server error (HTTP {0}: {1}).",
response.StatusCode,
response.StatusDescription));
StreamReader sr = new StreamReader(response.GetResponseStream());
JsonTextReader tr = new JsonTextReader(sr);
JsonSerializer ser = new JsonSerializer();
return ser.Deserialize(tr);
}
}
In the requestUrl
definition, I used the LipsumType.GetDescription()
extension method that I defined earlier to send the correct type based on what was chosen by the caller.
Don't forget to use the using() {}
when dealing with an object that implements IDisposable
. It will clean up after you and prevent you from leaving any machine resources open.
Notice the use of the ser.Deserialize<LoremIpsum>()
call (GitHub source). I was able to do this because we created a class directly from the JSON data. We then use this class with the Json (de)serializer to get an instance of the LoremIpsum
class containing the results of our call.
Here is the main()
method of the program that ties it all together:
static void Main(string[] args)
{
for (int i = 0; i < 10; i++)
{
// toggle between words and paragraphs
bool isEven = (i % 2) == 0;
bool isThird = (i % 3) == 0;
LipsumType lipsumType = isEven ? LipsumType.Paragraphs : LipsumType.Words;
// only start with Lorem Ipsum every third call
Debug.WriteLine(LoremIpsumUtil.GetNewLipsum(lipsumType, 7, isThird).feed.lipsum + Environment.NewLine);
// sleep for 1 second to give the server a rest
Thread.Sleep(1000);
}
}
This simply loops 10 times and makes a call to the lipsum.com json endpoint, toggling between paragraphs and words, as well as starting with "Lorem Ipsum" every third call. It also waits one second between each call to be friendly to the server.
Because we get back a fully populated object, we can also access the other properties on the LoremIpsum instance, like *.feed.generated
and *.feed.donatelink
.
Update: I've written a post that describes how to get PascalCased property names.