Fetching Stock Prices and Refactoring API Calls - FULL STACK WPF (.NET CORE) MVVM #7

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
it seems like this is everyone's favorite series and to be honest it's my favorite series too I really like working on this application so let's keep it going now the last few episodes we've been working on our major index service all the major index stuff and we finished up all of that last episode with the major index view model which we have here and now that we've finished up with that I want to bring up our Vizio stuff and so we finished up the major index service and now it's time to get into some other things now I really want to get some domain logic going like buying stocks selling stocks but to do that we're gonna have to create this I stock price service so that is what we're gonna do next and to do that we're gonna have to use the financial modelling prep API that we used for our major index service as well so here we are back on the financial modelling prep API website and the endpoint that we're gonna call is the stock real time price and they give this example here so all you have to do is put in this base URL right here and then just append the symbol that you want to search for so this is app what you click this and you get a symbol and you get the price which is what we really want so let's go ahead and create the stock price service we're gonna create the interface in our domain layer let's go ahead and create a new item and interface I accidentally named it interface 1 so let's rename it to a stock price service and we're creating this interface right over here and all we're gonna do is make this public and it's gonna have one method it's going to be a task so we can call it a synchronously and it's gonna return a double which will be the price and we're just going to call it get price and it's gonna take a symbol such as Apple which is I think a PPO or something like that make sure you import tasks and now we have our interface defined in our domain layer but now we're going to move into our financial modeling prep API project and we're going to define the actual service here and I don't know if I ever mentioned why we have our interface defined in the domain and our service to find out here and the reason we do that is because we want our application to depend on the interface and our domain layer and not have a very hard dependency on this financial modeling prep API so basically what that means is if the financial modeling prep ever like disappeared one day it's not like our application would heavily depend on it we're really just depending on this I stock price service but we would have to find another source for stock prices that could be a problem but hopefully we won't face that problem so let's create this new class we're just going to call it the stock price service and it's gonna be a public class and it's gonna implement the I stock price service that we defined and let's stub that out import our interfaces and let's make this asynchronous and there we go so let's take a look at our major index service because we're gonna use a lot of this code and then we're also gonna have to refactor so that we don't duplicate code so to do that let's actually get rid of this we're done here sure we can save that it's a full screen and actually the first thing I'm gonna do is I'm literally just gonna copy and paste all of this and let's just move right in here now let's import all this and we don't have this get your eyes suffix anymore so we're not gonna be using that but what we are gonna be doing is we're gonna be appending the symbol and then our endpoint is gonna change let's go ahead and grab that so I have that right here I'll try and put that in the description like that we get rid of the Apple at the end and we're gonna do the same thing we're gonna get an HTTP response message from this end point get it as JSON deserialize it we're not going to serialize it as a major index anymore what we're actually gonna have to do is create a new object to deserialize the JSON into so what I'm gonna do is I'm gonna create a new folder and we're gonna call this results and inside here I'm gonna call I'm gonna create a new class called stock price results so the reason I put this class in the financial modeling project and not into the domain layer project is because the rest of the application doesn't need to know about this object we're only using it to deserialize the result from the API which is unlike the major index object which is in our domain layer which needs to be used throughout the application and what this class is going to have is just properties that we can deserialize our response into so let me bring up the API again and when I click this we have basically two properties here symbol and price so we need to replicate these names as properties on our result object now I don't really want the symbol I kind of just want the price so what we're gonna do is I'm literally just gonna create one property on here called price and there's gonna be a double and that's all our stock price result needs to be so now if we go back to our stock price service what we can do is we can deserialize into a stock price result let's go ahead and import all of this and it'll automatically populate that price property with the result from the JSON response and this isn't a major index anymore this is a stock price result and it will call it stock price result and then what we're gonna do is return the price and there we go so now we have two services the stock price service and the major index service and they both call the financial modeling prep API now the issue here is that we're duplicating a lot of stuff between both of these services such as the URI so everything up to this v3 is duplicated between both of these URI strings and our services and then all of our D serialization is duplicated as well so what we're gonna do is we're gonna create a new create a new class and we're gonna call this the financial modeling prep HTTP clients and this is going to be a public class and it's going to inherit everything from HTTP client so we're basically just extending an HTTP client and making it for the financial modeling prep API so what we can do in this class is we can go ahead and create a constructor and we can set the base address which is on this HTTP client and we can set it to the part of the URL that is shared between both of these services so it's literally just the base address to the API so let's go ahead and cut this out and paste it in here and then we can also remove it from here so now since we're defining a base address what's going to happen is whenever we call get async for this URI it's going to automatically prepend the base address to this URI so now we're not duplicating it between our services because it's just defined as a base adjust right here but of course we're going to have to do is update this HTTP client it's going to have to now be the financial modeling prep HTTP client let's do that for both of our services and there we go so now we're not duplicating all of that URI that came between the specific stuff for the services now another thing that we're duplicating between our services is all of this deserialization getting the responses JSON calling the API so we can actually create a method on our HTTP client our custom HTTP client that does all of that for us and what that's going to be is a public method it's going to be a tasks that we can call it asynchronously and it's going to be based on a generic type because since we're doing D serialization we want this method to work for any type so we can deserialize it into any object and we're just going to call this get async and it's going to take that generic type and we're just going to take in the endpoint that we're calling as a parameter let's go ahead and import that we need to actually make this a sync and let's go into here and let's just copy this and move it into this method so same thing we're gonna call the endpoint we don't have to reference the client let me just call it get async and get a sync is available because it's on the HTTP client that we're inheriting from and then after that we can get the JSON and all we have to do after that is return the deserialize JSON and we're just going to deserialize into whatever type gets passed into this generic method and let's import JSON convert and there we go so we have all of this logic and our custom HTTP client so we can go ahead and call it here so we can say stock price result woops equals client dot get async and here we go we have our generic method and we're getting a stock price result from the URI and it's go ahead and await that and then same thing in our major index service we can get rid of all of that and now this is just gonna be client that get async we're gonna get a major index from the URI and there we go so now these are a lot more lightweight and we're sharing all of this stuff due to our custom HTTP clients now keep in mind this is a pretty simple approach to calling API is one thing you could do is maybe pass in a factory to these services that creates an HTTP client instead of doing it up but I feel like that would be a little bit overkill in this situation so we're just gonna keep it simple but anyways we have our service let's actually test out this get price service let's just go into our app dot sam'l and what we're gonna do is we're gonna create a new stock price service and we're just gonna call it get price and the symbol we're gonna use is I think that's Apple and let's go into our stock price service put a breakpoint right here and let's give it a go so we're loading everything up and actually we get a JSON reader exception and the reason actually I think the reason that we're getting that is if we look at our URI I think we need to put a slash at the end and then we actually have to get rid of these slashes I've had that issue before that might fix it let's go ahead and try this again and okay yeah that actually makes more sense that the base address has the slash instead of all of these so anyways let's look at the price and we get zero and we must have typed in the wrong maybe it's not Apple let me check actually it's a APL not a ppl it's actually an issue we're gonna have to address in a second but let's make sure that this works with the correct symbol and there we go okay so it works with the right symbol but if you have the wrong symbol it actually returns a zero and the reason that returns zero is because let's actually bring up this API and let me type in the a PPO which is a symbol that does not exist and as you can see it returns nothing and censer returns nothing when we deserialize that JSON into the stock price result there's no price field on the JSON to put into this price property so it just leaves it as zero so what we're gonna have to do is we don't want people buying stocks that don't exist so what we're gonna do is we're gonna throw an exception so if the stock price result dot price equals zero we're gonna throw something and we're gonna create a custom exception so this exception can actually go into our domain layer and we're going to create a folder call it exceptions and we'll call this invalid symbol exception and it's gonna be public and it's going to inherit from exception let's generate all these constructors I actually don't care about this protected one and it's gonna have a property on it which is the symbol and then all of these constructors will take in the symbol let's go ahead and copy that into all of these and then inside the constructor will set the symbol equal to symbol and there we go okay so we have our exception let's go into here and let's throw a new invalid symbol exception and we'll pass in first we're going to import it pass in the symbol that they tried to use and I think this if statement is safe so if the price is zero I think we should throw an invalid symbol because I don't think there's I don't think it's possible for a valid stock to have a price of zero because then someone could literally just buy unlimited stocks but correct me if I'm wrong in the comments because otherwise what the fix this up but anyway so let's drop a breakpoint here and let's throw an invalid symbol in here and let's make sure we're hitting this exception and there we go okay so we got an invalid symbol now while we're on the topic of exceptions I was actually looking at this major index service and I saw that the default for this switch case right here is just two returned Algerians and I actually don't like that I kind of want to throw an exception here so that if I ever add another major index type sometime down the road I don't want it to automatically be calling Dow Jones because then I might never realize that I didn't implement this switch case so we're just gonna throw a basic exception and say major index type does not have a suffix defined so that's a little bit cleaner and now that we're gonna clean up mode I want to show you guys another thing that we can clean up so if we run this you guys might have noticed that ideally we want this to say Dow space Jones and then we might want this to say s and P space 500 but the reason they don't say that is because we're binding that little title text block to this major index type so it's just running to string on these enum values and just printing these results and what I noticed was if I bring up this financial modeling prep API it seems like they're like updating this pretty frequently so if I go to this major indexes and let's look at Dow Jones now there's a property called index name so what we can do is we can go into our major index and we can just grab that index name now so it's a property called index name and now if I go to our major index service when we deserialize it's going to fill that index name property and I'll show that right here so we get the major index index name S&P 500 that is great so now if I go into our believe it's a control a major index card instead of binding to the type we can bind to the index name and now if we run the application it's just gonna be so pretty I'm so excited Oh get rid of this breakpoint and there we go it looks very nice now the last thing I want to clean up has to do with our database and I know we haven't done a lot with our database lately but very soon we're gonna start putting data into the database and interacting with it a lot more so I want to make sure that our table structure is ideal and one thing I noticed was if we look at this object we named it stock and stock is on our asset transaction and the reason I don't like that is because I feel like stock isn't the right name because down the road we might have an object or a class called stock that has properties such as name of the company changes last dividend payout daily low stuff like that and if we have that all on this stock object that's a problem because our asset transaction actually has a column for each property on the stock object but we've really only ever one our asset transaction object or table that have columns for these two rows so what I'm going to do is instead of calling the stock we're gonna save that name for later and we're gonna call this let me rename it up here we're gonna call this asset we could rename all references and then in our asset transaction we're gonna name this property to asset as well and now we're going to have to do is update our database so let's go ahead into our package manager console I believe we're gonna have to set this as our startup project and let's add migration and we'll name this migration stock to asset and I have an issue because I actually reinstalled Visual Studio so I don't have version 2.2 anymore so what I need to do is go into my enemy framework and you guys can do this too let's go ahead and upgrade our framework to dotnet core 3.0 because why not i mean our WPF project uses 3.0 let's do it in any framework as well so now let's go ahead and try this again and default project needs to be in any framework to add migration again and there we go we get our migration and all we're doing is renaming columns so let's go ahead and update the database and there we go now if we go into our databases we have simple trader DB we got tables as the transactions columns and now it says asset instead of stock so that was just a simple a little cleanup I wanted to do just for the future and even though that rename from stock to asset seems like a trivial change I feel like it just makes more sense for the class as a transaction to have a property that is called asset instead of stock that is of the type asset instead of suck so it's it's just all about assets so we get a little bit a little bit of consistency there too so that's going to wrap it up for this part of the series so we created our stock price service we implemented a stock price service and our financial modelling prep API project we refactored both of our API services by creating this custom financial modeling prep httpclient we created a custom exception so if you try to get the price of a simple that doesn't exist then you're gonna have to deal with this exception and then we also renamed our stock object to assets so we can use stock sometime down the road for a more complicated object and not have to worry about all of the properties of a stock coming into the database so that's gonna wrap it up thank you guys for watching I hope you guys learned something from this episode if you have any questions comments or criticisms leave them below in the comment section but other than that leave a like or subscribe for more thank you
Info
Channel: SingletonSean
Views: 5,295
Rating: undefined out of 5
Keywords: wpf, mvvm, easy, hard, difficult, switch, views, microsoft, visual, studio, binding, viewmodel, property, inotifypropertychanged, class, interface, user, control, window, learn, how to, architecture, pattern, new, correct, switching, toggle, button, content, main, programming, tutorial, full, stack, entity, framework, model, access, object, core, .net, c#, service, layer, walkthrough, project, finance, stock, trade, trading, development, background, user interface, price, exception, handling, httpclient, endpoint, fetch, refactor, clean, rest, api
Id: TFfFVHBFqjY
Channel Id: undefined
Length: 24min 8sec (1448 seconds)
Published: Sat Jan 25 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.