Building Microservices with Go: 7 Documenting RESTful APIs with Swagger

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[Music] [Music] [Music] hey there and welcome back to another show and I do apologize running a little bit late today well and camera no camera camera camera want to behave no okay all right I apologize about that so let's get started what are we going to look at today so what I want to to look at today is kind of continuing where we we left off last time and like some of the things that we were looking at we've been building out this API and there's like a full playlist of the previous show but we looked at Jason validation now one of the things that I want to start to kind of cover this time is looking at documentation because document ating document ating I think I've just recreated a new word they're documenting an epi is is really really useful it's useful for your own consumption but you know it's it's kind of also useful for other people the key thing about billing micro services is that you can have a lot of them and a lot of people are gonna be coming and asking you saying hey how does this work where's the docs I mean trying to look through the source code I don't understand because it's go and I'm a JavaScript front-end developer so you can do yourself a favor and just kind of take a good approach of documenting things so swagger kind of is as I suppose the the open API spec which which the industry seems to have settled around for restful api and in it's a pretty nice tool what we are going to look at is how we can start using swagger with our with our existing sort of API and using go swagger because what I want to be able to do is I want to be able to add my documentation to my go code and for it to be automatically generated and that's what we're gonna do so let's take a look let me just zoom that up for you maybe not that much okay so what we what we have is is our our API that we've been working on for the the last sort of few last few weeks there and we've we've started to set out these routes and we want to now be be looking at how we can we can document this so we use go swagger and the the nice thing about go swagger is that go swagger is going to allow us to to generate kind of all of this code from from within our API so let's take a look well let's have a look at the entry point so what we want to be able to do is we want to kind of write some very sort of top-level documentation for for our API so we can add the documentation to to our handlers and let me just quickly fly over to the top-level Doc's here and we'll find that somewhere we're looking for the package Doc's and of course there we go so we we kind of have this top-level documentation and this is kind of letting people know what is the intention of the service it also setting out some things like are we going to be using an HTTP scheme an HTTP scheme some contact information so that they know where to file bug reports and and some basic kind of stuff around the kind of the the inputs and the outputs of the system are you gonna be using gzip potentially JSON XML whatever that could be and you can also define the the sort of security elements of this so you know anything that's covered within the this Waguespack we can and put in here we don't have any security yet in this API we'll be looking in security in just a sort of a few episodes time but but first let's let's kind of add that top level documentation and we can at least just kind of get things generating so we're using this the the documentation godox go doc stuff so we're doing classification of product api okay and then we're gonna kind of just say documentation for product api so we will set the the schemes not spelling it like that we want and we're gonna set that to http and we're gonna set the the base path so the other useful thing about setting out your documentation using the the swagger sort of format is you can actually also use swagger to generate clients so if somebody is let's say building a ruby integration to your micro service then what they can do is they can actually consume your swagger definition and they can use that to auto code gen themselves an api of course and go you could use your swagger spec as well to to code gen and an api client that other people could consume is just a package but wait we're just sending out these basic details so we're just saying that the base path is is just slash the the version well we're just on version one it consumes so this api only interacts with application Jason it's Jason and Jason out so application Jason and what does it produce well same thing Jason so whoops really can't type today so we're gonna set that out like that and then what we're gonna do is we're using the the swagger meta tag and that's just gonna give the the go swagger library a chance to be able to generate our Doc's so to generate the Doc's we're actually gonna use the the go swagger tool so rather than kind of running that every time we'll we'll have that as part of our CI flow and what I kind of like to do is is add stuff like this to a make file so rather than having kind of all of these random sort of commands that don't you know about in your head put them in a make file and and then you can document them in the readme make it easy for other folks too to be able to consume your stuff so what I want to be able to do is I'm going to use the the go swagger tool and it's literally just swagger generate so let's create a an item in the make file and what you call them recipes make buildconfig things swagger okay and this is going to we're gonna switch go module off as per the docs and we're gonna run swagger generate spec and then where do we want to generate this back to well I'm just gonna put it in the root and I'm gonna say swagger llamo and then I'm putting the scan models and what that's going to do is that's also going to be able to run through and build my documentation for for my models that I'll define and all of that will be a little clearer in a little while but let's just first let's just see that run so I've because I've got that I can now just do make swagger so that's running and you can see there that it generated me a swagger far then you see so that documentation that I put on my API has generated this start of my swagger document which is really nice it's of course let me just prove that that I'm I've got no smoke and mirrors because honestly it's gonna take me longer to do smoke and mirrors and it is just code this like first time but you see the difference there I just made that change so we've we've got that running where do you install swagger from I hear you cry well you can just use a simple go get so again where we can just do go over 111 modules off go get and it's just - you github.com slash go swagger go swagger command swagger so we can just do it like this you can call this install so if you if we just quickly bounce over to that URL I will put all of these these URLs into the the description but it's a really nice project and the I was looking at the documentation there which is in the project but you can have a look at the repo again everything's nice and written and go so and it's all well maintained glass commit there 12 days ago so one one kind of nice thing that we can do with this in our make is why don't we call this check install and then rather than just kind of running this what we can say is we can say which swagger and what what the which command does is it'll basically check to see if there's an existence of a command on your on your UNIX system work on a Mac as well and if it doesn't exist then what we're gonna do is we're gonna run the go get so then in my my make file I can just have a nice single line make swagger and that will check the install and install the tool if I need it as well alright so we what we're doing alright we've got our kind of very basic scaffolding running so the question is now how do we how do we start sort of documenting these api's so what we what we can do is we can start to to kind of run through and we can start adding the the documentation elements for each of the the api's right so we're going to use again more more sort of go dark but the nice thing about this is that I can put this in with my my actual API documentation itself so let's say we say get products returns the the API and then what I can do is I can define my my swagger route so you say running comment swagger root verb which is gonna be get the UL power URI path your own products and well what is it gonna do well it's kind of the name I suppose all that the surreally the grouping so products and the the name so we're gonna we're not calling in gap products we're calling it lists products we're gonna kind of take a more of a controller based approach that's what we want to call it in our documentation because it's gonna be different from what we we call it in our in our code base so we can we can define that and then we can say well what does it do well it returns a list of products nice and easy so if we if we kind of just generate generate that then you can see that we've now got this path element but we're not we're not quite done yet because we want to add a little bit more information to this we need we need something you know a little bit richer than we just have here because what we can we can do is we can do things like well what does it what are the responses so I can give a hint and I can say responses and it returns a 200 and that is gonna have a list of of products so I can say okay products response oops and that needs to be a comment as well so so this is kind of nice so I can actually define the the list of of objects so this product response is actually a strut inside of your your documentation and it's not it's not going to be directly the the product you know just the list of products we we kind of need to add a little bit of finesse and some more documentation onto that so it you know it you're not direct but it's still pretty pretty easy going so let me just close down some some of these files get them out of my way so let's add that so we've got our product API here and we can add some some documentation so I'm gonna define it tight I'm gonna call it products response I'm not actually gonna use this I'm literally only using it for for my documentation but I can define like a body here and I can say data there's gonna be a slice date a dot product so like everything else I add my my documentation so I can say well a list of products ok and what I can then do is I can add you know it's more more document all as some documentation it's going to appear in my swagger doc so all product in the system and then again what I'm going to be doing is I'm using this metadata so if I kind of look at all of this documentation and you've got to kind of look at all of the specification here on go swagger but a response object has an annotation of in so where to find the field so this can be in the body or it could be in the path or it could be in you know something else but but this is quite quite nice because we we get to kind of define this and I'm not gonna do stuff like this because I'm gonna show you how we can annotate our models but you've got the ability to kind of write really really rich sort of documentation and you literally get out what you put into this so it's it's worthwhile spending a little bit of time but anyway in body all right let's run our documentation again and what we got now this is nice right so now we can see that we've got a response it says it's gonna do a 200 it's gonna return a response products so we are we're kind of really really starting to to get someone but if you look well its defined it as a response here but I haven't got the actual object and that's because again I can't just define it like this I've got to be using those swagger matter documentation tags phone seis swag a response and then I give it its name product response generate my Doc's again okay and you see but now it's pulled in all of that object from from my data package and it's automatically added it to my swagger documentation I haven't had to do anything on this it's literally just pulled it in all because I've defined this this wrapper for for my my documentation and this is really cool I'm getting Sam I write so I've now got in pretty quickly I think this sort of documentation that's starting to to build up but wouldn't it be nice if I could serve this documentation you reckon I think it would I think it'd be pretty sweet so what if I was to add the documentation to my actual API itself and give it a kind of a nice rich UI it's why I can do that too so what we can do is we can add a Docs handler and we're going to use some special middleware so I'm going to say well it's gonna be on get so it's gonna be the what did I call this the GATT ruda and we're gonna do handle we just go and add the docs path and what I want to do is add a special handler here what's where do I get that handler from well I'm going to use redox so redox actually has a handler for serving my my swagger spec directly from my goal code which is is pretty pretty amazing and you get this really nice rich eye-to-eye so I can just use their middleware and I can automatically add this this to my UI so it's making things really easy for folks so that's going to be in the the package the redock middleware package so first to use that what I need to do is I just need to specify some options so let's add middleware dot three and dark ops so in the reader Copts I've got a bunch of stuff that I can specify in here but I'm just going to specify my spec URL and that's because the the base spec URL is not gonna be looking for a yawl it's gonna be looking for adjacent I just want to change that to Yama and then I can actually define my my middleware so this is a middleware dot redock with the options okay right so we do we do that so that's going to live in the the redock middleware package which you can find at let me just open up a web browser here we get it in github.com slash let's go open API runtime middleware so the go open API runtime has a package which has got the capability to to do this documentation so we've got this middleware which is gonna be allow us to present that that redock and again I'll stick the link in there but the nice thing about building a lot of stuff and go is if you know which packages to use you can build some stuff out really really quite quickly alright so I'm just gonna add whoops not like that I want let me add that package so now what I want to be able to do is to be able to serve my Docs so that should be enough kinda but let me show you is why only kinda go run main dot go undefined upwards okay typos tastic alright this is now running so now if I go to localhost and 1990 Docs oh well but kind of nearly there but that looks a bit broken right so let's look at why that is so the reason is that it says era downloading localhost 1990 swagger because what the redock website is it's a lots of JavaScript based website on if it uses reactor or whatever but it's it's JavaScript based so the browser is actually attempting to download the swagger file from my server itself but well my server itself is not serving that file yet that easy enough to fix so in go you've got the the concept of a built in file server and we've I don't believe we've looked at serving files yet I'm gonna kind of save that for probably the next show where I want to talk a little bit about serving files and gzipping and stuff like that but it exists so we have that that Rooter and what we can do is we can just write another handle so I'm gonna do get ruder dot handle and then what's the path going to be well the path is going to be our our swagger file so swagger dot llamo so remember when when you're adding the the roots the roots are all going to be you know that kind of absolute so what when somebody requests swagger dot yam all what do we want to happen well we we kind of just want to redirect that at a file server so I can just say HTTP dot file server and HTTP dot directory dot slash let me just run that and I'll explain what's going on in that all right so first things first we now have our swagger because we've literally with that one line of code just added a basic file serving capability to our go API but now with our swagger Doc's look at that we've now got our UI and this again is this is built into the the URL that we were just just looking at earlier on just I think pretty cool so how did we how do we do that so how did we serve that that swagger file well what we did was we we kind of we added a new handler and the handler is passing that is looking explicitly for this file so HTTP file server if we we look at this what it is is a special handler which is built into the goal HTTP package for serving file requests so what this is is going to do is it's going to look for the file path that comes in so in this instance swagger llamo in the given directory so the directory that you are specifying I'm using this HTTP dir and that's the path so that's my current working folder because that's where my swagger Aoyama lives and the file server is then going to look for swagger tamil inside of this HTTP dir if it finds it it'll serve it if it doesn't then it'll bounce it and really really is that quite really really simple when you're serving large files in go and this is one of the things that I'm gonna look at in the next video you want to be looking at things like cheese ipping as well because if you're signing a large file over the Internet if you gzip it it's gonna reduce the battle bandwidth and it's gonna actually speed up the core problem isn't zipping in terms of time it's really gonna be data transfer so the smaller those files the quicker your webserver is actually going to be and we're gonna look at that in the next episode I think what I'm going to do is we'll look at that we're gonna tidy up a couple of little bits of pieces but where what kind of we're getting through there but back to this so there we go right we've got a get API what about well what about something which would kind of take say a file parameter so let's say the delete method if you look here our delete method has an API parameter in the URI path which is the name or surreally the ID of the item that we want to delete well we can kind of add that really really sort of simply as well so let's um let's take a look so how do we how do we define that again what I'm doing is I'm I'm kind of I'm just separating things up a little bit but I'm going to add my annotation again onto onto here it's gonna be very very similar in fact you know I'm gonna do what everybody should do which is cut and paste so my swagger route remember that metadata and again let's just bounce quickly over into the docs I want to just show you show you that swagger meta all of these different sort of elements here and then route so swagger route has all of these various different properties that you can set and various different patterns and things like that and that the documentation is excellent you'll find all of the examples and things like that in there but we we need to add that so we're doing swagger root it is delete and it is product / ID and we can specify the parameter ID somewhere else and we'll we'll take a look at how we're going to do that in the moment but at the moment this is going to be delete product so it's still in our products group the name of it we're gonna call delete products and well if it's successful it's just gonna return no content and let me just quickly update that delete products return oh no it does not that leaps a product from database okay so we need to define two more of those wrappers if you remember so we need to define one for the ID and we need to define one for there's no comment content so I'm putting kind of any of those sort of generic elements because you probably find you reuse them time and time again I'm just putting them in my this products file here where I know where I can where I can find them so the ID first so how do I add a parameter so it is swagga parameter and let's again just quickly look over the documentation for parameter and you can see you kind of starting to get used to this convention I think but we can kind of see where the parameter is going to be you can specify maximum values for it a pattern in case it's a string so we could kind of use a regular expression if it's got a number of items you know that it's very very very very flexible and we can do some some really really nice things again the kind of the nice thing around this is when you're kind of code Jenning it's just gonna make things really really easy but it also makes it very clear in terms of the documentation so so I get parameter which parameter is it well it's a let's call it I don't know delete product yeah I suppose it was generic we could we could we could call it something more but delete product okay so what is the delete product parameter well again we're going to just define a type so we'll say type we're gonna say product ID whoops ID parameter wrapper struct and we'll we'll kind of look at that we're gonna put that in now is it gonna be in body nope in path okay is it required yes because if you are going to be deleting an item you've got to have the the Product ID require require require require IO read all right and then we can define the type so it's gonna be called and we're just gonna say Jason but this is our parameter wrapper so what is the the name yeah we can add this description so we can say the ID of the product to delete from the database again in path blah blah so sorry I made a I think I made a mistake earlier on I was saying that what we're gonna call this this isn't the name sorry this is the function to which it relates so if we look over here we created this route and we called it delete product so for the parameter ID I'm referencing it here so I'm just doing this cross-referencing and I could have multiple of these annotations if I was using the product in more than one one location but you know we're we're kind of get in there so I'm gonna leave my server running and I'm just gonna generate my my swagger again what do we got so smart well yeah it's power where did I make that typo unknown annotation well yeah parameters I did say this show was warts and all the knife I could make a perfect but who doesn't make mistakes I certainly make plenty what do we got oh well we got an arrow because we haven't defined no content because again we've kind of we're making these references but for the documentation to work we kind of need to kind of define all of these sub documentation bits you know it may fight feel like it's a little bit of a sort of a chore for you but it's always the keyboard you know but you're absolutely right it may feel like a little bit of a chore but honestly once you kind of get a lot of this stuff set up it moves along really really really quickly so let's just add our no content wrapper and we're just gonna say type product no content strut we're gonna say swagger response gosh no content well it has no content because it has no body so let's just generate that again and we'll just quickly bounce over here and then refresh that and then we can see that we're kind of getting getting all of this sort of documentation and it's it's really starting to kind of richly richly be defined which which I think's really nice so I'm pretty much done I don't want to go through and do all of these elements because it'll bore you to death but what I am going to do is I will as always have the source code in the link below and I will upload everything at the end of the show so it'll be it'll be available in about an hour or so and what I just wanna show you before I disappear is annotation of some objects and a little bit more more sort of depth because you know it's it's all well and good here we've got this product and it's kind of annotated well it's annotated okay we can kind of see some response schema and stuff but there's no real rich description around it we can add all of those rich descriptions by using model tag and the model tag allows us to to kind of really put a lot of definition around our objects so we you know we what we looked at validation in the previous episode we can actually describe the validation elements that are going to be required for for the user by by using the the swagger model let's um let's quickly take a look at how we can we can do that for our product so I've been on the fence here and and I was like I've got this data block and it has a product and do I really want to be adding swag and metadata it feels like you know feels muddy I've got swagger Doc's inside my product and I've got them in my fan blows and I can came to peace to it I was just you know I don't really feel like I liked it much but at the same time it doesn't really bother me I don't find it it that intrusive in fact in some ways the documentation even though it's swagger specific can help with the sort of the general readability so what I'm gonna do I'm gonna use swagger model so again it's all about that metadata and then to to kind of validate each of these sort of elements then you know we we kind of need to specify this sort of documentation on on each of the the various different things so let's just quickly add an example and then I can run that and and show you what's going on so we're going to say the the ID of the user is it required yeah let's just say it's gonna be required minimum value minimum value is gonna be one this is just an ID it's actually just gonna be an auto increment an ID so not not such a useful bit of help there but we can kind of see what's going on now if we we kind of generate our Swagger's back again and again I just want to kind of go over here and then I'm gonna refresh but you know you can see now that I'm seeing showing this is required I've got the ID required for the user you can kind of see that it must be greater than one I've really done a great deal there but it's kind of this I really like this this is just free right and your users will really love this because you're helping them with the documentation you know you you don't have to use the the kind of the built in and points for your your swagger Doc's if you want you can take these swag uyama files and you could have a read oxide somewhere else you can have central documentation generated for for your company or whatever but I think this is quite nice to bundle this stuff up like this because you're gonna package in a docker container and you've always got that convention of slash Docs then for every micro service and your system every developer knows that they just need to spin up the micro service and hit slash Docs to get the swagger redock documentation and they can just hit the kind of the half of slash swag oh yeah mall is exposing the API documentation a security risk probably not I mean if this is a public API kind of showing what the documentation is I don't think you're really going to be helping anybody I don't believe in security by obfuscation I think security is is proper security but you know certainly if you've got this an internal it's probably going to be fine from a from a perspective certainly if you have a public API that people are going to be consuming providing them with swagger Doc's they're probably gonna love you for that because they can literally just throw a code generator at at this end point and generate a client maybe that's what we'll do mid week maybe mid week what I'm going to show you is how we can actually be the consumer of it it kind of completes that circle I think yeah let's do that all right well we're pretty much done for now I don't want to spend too much more time on this it it's kind of just gonna be very much more the same but I will complete the the documentation for this API offline and it'll be available and the github repo I'm just gonna check this code in right now so get let's have a look all we got here that looks all okay get add dot get commit added documentation and I'm just going to push that to the the branch episode 7 episode 7 well come on Oh orig orig orig in all the type and mistakes Ivan I tell you this keyboard needs to be replaced it's probably the key caps I bet you dodgy keycaps that's what's born on but that's they're all of the documentation I've been pushing as we kind of go along with with this stuff to to the repo oh so many repos I've just been working on so much stuff recently where is it where is it too many repos but you can find out at the repo here and then there's the branch for today's code I'm gonna tidy this up and I'm going to push an update right now and we're done now I kinda wanna thank you again so much for for watching got the funky music going on there but I really appreciate it I hope you're finding this series useful and of course if you are you know please like subscribe it helps me push the content and and that's all that's always a good thing share it with your friends but for now I want to say goodbye and I will look forward to seeing you all next time midweek laters
Info
Channel: Nic Jackson
Views: 31,133
Rating: undefined out of 5
Keywords: go, microservices, JSON, RESTful
Id: 07XhTqE-j8k
Channel Id: undefined
Length: 46min 34sec (2794 seconds)
Published: Sun Feb 09 2020
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.